Display types' memleak at Scilab exit
[scilab.git] / scilab / modules / ast / src / cpp / types / inspector.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2011 - DIGITEO - 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 <string>
14 #include <iostream>
15 #include <map>
16
17 #include "inspector.hxx"
18 #include "types.hxx"
19
20 namespace types
21 {
22 #ifndef NDEBUG
23 std::vector<InternalType*> Inspector::m_vIT;
24
25 size_t Inspector::getItemCount()
26 {
27     return m_vIT.size();
28 }
29
30 size_t Inspector::getUnreferencedItemCount()
31 {
32     int iCount = 0;
33     for (size_t i = 0 ; i < m_vIT.size() ; i++)
34     {
35         if (m_vIT[i]->getRef() == 0)
36         {
37             iCount++;
38         }
39     }
40     return iCount;
41 }
42
43
44 void Inspector::addItem(InternalType* _pIT)
45 {
46     types::GenericType* pGT = _pIT->getAs<types::GenericType>();
47
48     if (pGT)
49     {
50         //std::wcout << L"addItem " << pGT->getTypeStr() << L"[" << pGT->getSize() << L"] : " << pGT << std::endl;
51     }
52     else
53     {
54         //std::wcout << L"addItem " << _pIT->getTypeStr() << L" : " << _pIT << std::endl;
55     }
56     m_vIT.push_back(_pIT);
57 }
58
59 void Inspector::removeItem(InternalType* _pIT)
60 {
61     std::vector<InternalType*>::iterator it;
62
63     for (it = m_vIT.begin() ; it != m_vIT.end() ; it++)
64     {
65         if ((*it) == _pIT)
66         {
67             types::GenericType* pGT = _pIT->getAs<types::GenericType>();
68
69             if (pGT)
70             {
71                 //std::wcout << L"removeItem " << pGT->getTypeStr() << L"[" << pGT->getSize() << L"] : " << pGT << std::endl;
72             }
73             else
74             {
75                 //std::wcout << L"removeItem " << _pIT->getTypeStr() << L" : " << _pIT << std::endl;
76             }
77             m_vIT.erase(it);
78             break;
79         }
80     }
81 }
82
83 InternalType* Inspector::getItem(size_t _iPos)
84 {
85     if (_iPos >= m_vIT.size())
86     {
87         return NULL;
88     }
89     return m_vIT[_iPos];
90 }
91
92 InternalType* Inspector::getUnreferencedItem(size_t _iPos)
93 {
94     size_t iCount = 0;
95     for (size_t i = 0 ; i < m_vIT.size() ; i++)
96     {
97         if (m_vIT[i]->getRef() == 0)
98         {
99             if (iCount == _iPos)
100             {
101                 std::wcout << L"getUnreferencedItem : " << m_vIT[i] << std::endl;
102                 return m_vIT[i];
103             }
104             iCount++;
105         }
106     }
107
108     return NULL;
109 }
110
111 std::wstring Inspector::showItem(size_t _iPos)
112 {
113     std::wstring st;
114     InternalType* pIT = getItem(_iPos);
115     if (pIT == NULL)
116     {
117         st = L"NULL";
118     }
119     else
120     {
121         st = pIT->getTypeStr();
122     }
123     return st;
124 }
125
126 std::wstring Inspector::showUnreferencedItem(size_t _iPos)
127 {
128     std::wstring st;
129     InternalType* pIT = getUnreferencedItem(_iPos);
130     if (pIT == NULL)
131     {
132         st = L"NULL";
133     }
134     else
135     {
136         st = pIT->getTypeStr();
137     }
138     return st;
139 }
140
141 void Inspector::deleteItems()
142 {
143     InternalType** pIT = new InternalType*[m_vIT.size()];
144
145     //copy item values
146     for (size_t i = 0 ; i < m_vIT.size() ; i++)
147     {
148         pIT[i] = m_vIT[i];
149     }
150
151     //delete each item
152     for (size_t i = 0 ; i < m_vIT.size() ; i++)
153     {
154         delete pIT[i];
155     }
156
157     //check vector update
158     if (m_vIT.size() != 0)
159     {
160         printf("Oo\n");
161     }
162 }
163
164 void Inspector::displayMemleak()
165 {
166     std::map<std::wstring, size_t> statistics;
167
168     if (m_vIT.size() != 0)
169     {
170         // construct the statistic map
171         for (size_t i = 0; i < m_vIT.size(); ++i)
172         {
173             statistics[m_vIT[i]->getTypeStr()]++;
174         }
175
176         // display the result
177         std::wcerr << L"Memory leaked, please file a bug on http://bugzilla.scilab.org" << std::endl;
178         for (auto it = statistics.begin(); it != statistics.end(); ++it)
179         {
180             std::wcerr << L"    " << it->second << L" " << it->first;
181
182             // list the not free-ed pointers
183             std::wcerr << L" : ";
184             bool isFirst = true;
185             for (size_t i = 0; i < m_vIT.size(); ++i)
186             {
187                 if (it->first == m_vIT[i]->getTypeStr())
188                 {
189                     if (isFirst)
190                     {
191                         isFirst = false;
192                     }
193                     else
194                     {
195                         std::wcerr << " , ";
196                     }
197                     std::wcerr << m_vIT[i];
198                 }
199             }
200
201             std::wcerr << std::endl;
202         }
203
204     }
205 }
206
207 #endif
208 }