TypeCategoryMap.cpp revision 263363
1//===-- TypeCategoryMap.cpp ----------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/lldb-python.h"
11
12#include "lldb/DataFormatters/TypeCategoryMap.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18
19using namespace lldb;
20using namespace lldb_private;
21
22TypeCategoryMap::TypeCategoryMap (IFormatChangeListener* lst) :
23m_map_mutex(Mutex::eMutexTypeRecursive),
24listener(lst),
25m_map(),
26m_active_categories()
27{
28    ConstString default_cs("default");
29    lldb::TypeCategoryImplSP default_sp = lldb::TypeCategoryImplSP(new TypeCategoryImpl(listener, default_cs));
30    Add(default_cs,default_sp);
31    Enable(default_cs,First);
32}
33
34void
35TypeCategoryMap::Add (KeyType name, const ValueSP& entry)
36{
37    Mutex::Locker locker(m_map_mutex);
38    m_map[name] = entry;
39    if (listener)
40        listener->Changed();
41}
42
43bool
44TypeCategoryMap::Delete (KeyType name)
45{
46    Mutex::Locker locker(m_map_mutex);
47    MapIterator iter = m_map.find(name);
48    if (iter == m_map.end())
49        return false;
50    m_map.erase(name);
51    Disable(name);
52    if (listener)
53        listener->Changed();
54    return true;
55}
56
57bool
58TypeCategoryMap::Enable (KeyType category_name, Position pos)
59{
60    Mutex::Locker locker(m_map_mutex);
61    ValueSP category;
62    if (!Get(category_name,category))
63        return false;
64    return Enable(category, pos);
65}
66
67bool
68TypeCategoryMap::Disable (KeyType category_name)
69{
70    Mutex::Locker locker(m_map_mutex);
71    ValueSP category;
72    if (!Get(category_name,category))
73        return false;
74    return Disable(category);
75}
76
77bool
78TypeCategoryMap::Enable (ValueSP category, Position pos)
79{
80    Mutex::Locker locker(m_map_mutex);
81    if (category.get())
82    {
83        Position pos_w = pos;
84        if (pos == First || m_active_categories.size() == 0)
85            m_active_categories.push_front(category);
86        else if (pos == Last || pos == m_active_categories.size())
87            m_active_categories.push_back(category);
88        else if (pos < m_active_categories.size())
89        {
90            ActiveCategoriesList::iterator iter = m_active_categories.begin();
91            while (pos_w)
92            {
93                pos_w--,iter++;
94            }
95            m_active_categories.insert(iter,category);
96        }
97        else
98            return false;
99        category->Enable(true,
100                         pos);
101        return true;
102    }
103    return false;
104}
105
106bool
107TypeCategoryMap::Disable (ValueSP category)
108{
109    Mutex::Locker locker(m_map_mutex);
110    if (category.get())
111    {
112        m_active_categories.remove_if(delete_matching_categories(category));
113        category->Disable();
114        return true;
115    }
116    return false;
117}
118
119void
120TypeCategoryMap::Clear ()
121{
122    Mutex::Locker locker(m_map_mutex);
123    m_map.clear();
124    m_active_categories.clear();
125    if (listener)
126        listener->Changed();
127}
128
129bool
130TypeCategoryMap::Get (KeyType name, ValueSP& entry)
131{
132    Mutex::Locker locker(m_map_mutex);
133    MapIterator iter = m_map.find(name);
134    if (iter == m_map.end())
135        return false;
136    entry = iter->second;
137    return true;
138}
139
140bool
141TypeCategoryMap::Get (uint32_t pos, ValueSP& entry)
142{
143    Mutex::Locker locker(m_map_mutex);
144    MapIterator iter = m_map.begin();
145    MapIterator end = m_map.end();
146    while (pos > 0)
147    {
148        iter++;
149        pos--;
150        if (iter == end)
151            return false;
152    }
153    entry = iter->second;
154    return false;
155}
156
157bool
158TypeCategoryMap::AnyMatches (ConstString type_name,
159                             TypeCategoryImpl::FormatCategoryItems items,
160                             bool only_enabled,
161                             const char** matching_category,
162                             TypeCategoryImpl::FormatCategoryItems* matching_type)
163{
164    Mutex::Locker locker(m_map_mutex);
165
166    MapIterator pos, end = m_map.end();
167    for (pos = m_map.begin(); pos != end; pos++)
168    {
169        if (pos->second->AnyMatches(type_name,
170                                    items,
171                                    only_enabled,
172                                    matching_category,
173                                    matching_type))
174            return true;
175    }
176    return false;
177}
178
179lldb::TypeFormatImplSP
180TypeCategoryMap::GetFormat (ValueObject& valobj,
181                            lldb::DynamicValueType use_dynamic)
182{
183    Mutex::Locker locker(m_map_mutex);
184
185    uint32_t reason_why;
186    ActiveCategoriesIterator begin, end = m_active_categories.end();
187
188    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
189
190    for (begin = m_active_categories.begin(); begin != end; begin++)
191    {
192        lldb::TypeCategoryImplSP category_sp = *begin;
193        lldb::TypeFormatImplSP current_format;
194        if (log)
195            log->Printf("\n[TypeCategoryMap::GetFormat] Trying to use category %s", category_sp->GetName());
196        if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why))
197            continue;
198        return current_format;
199    }
200    if (log)
201        log->Printf("[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
202    return lldb::TypeFormatImplSP();
203}
204
205lldb::TypeSummaryImplSP
206TypeCategoryMap::GetSummaryFormat (ValueObject& valobj,
207                                   lldb::DynamicValueType use_dynamic)
208{
209    Mutex::Locker locker(m_map_mutex);
210
211    uint32_t reason_why;
212    ActiveCategoriesIterator begin, end = m_active_categories.end();
213
214    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
215
216    for (begin = m_active_categories.begin(); begin != end; begin++)
217    {
218        lldb::TypeCategoryImplSP category_sp = *begin;
219        lldb::TypeSummaryImplSP current_format;
220        if (log)
221            log->Printf("\n[CategoryMap::GetSummaryFormat] Trying to use category %s", category_sp->GetName());
222        if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why))
223            continue;
224        return current_format;
225    }
226    if (log)
227        log->Printf("[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
228    return lldb::TypeSummaryImplSP();
229}
230
231#ifndef LLDB_DISABLE_PYTHON
232lldb::SyntheticChildrenSP
233TypeCategoryMap::GetSyntheticChildren (ValueObject& valobj,
234                                       lldb::DynamicValueType use_dynamic)
235{
236    Mutex::Locker locker(m_map_mutex);
237
238    uint32_t reason_why;
239
240    ActiveCategoriesIterator begin, end = m_active_categories.end();
241
242    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
243
244    for (begin = m_active_categories.begin(); begin != end; begin++)
245    {
246        lldb::TypeCategoryImplSP category_sp = *begin;
247        lldb::SyntheticChildrenSP current_format;
248        if (log)
249            log->Printf("\n[CategoryMap::GetSyntheticChildren] Trying to use category %s", category_sp->GetName());
250        if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why))
251            continue;
252        return current_format;
253    }
254    if (log)
255        log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning empty SP");
256    return lldb::SyntheticChildrenSP();
257}
258#endif
259
260void
261TypeCategoryMap::LoopThrough(CallbackType callback, void* param)
262{
263    if (callback)
264    {
265        Mutex::Locker locker(m_map_mutex);
266
267        // loop through enabled categories in respective order
268        {
269            ActiveCategoriesIterator begin, end = m_active_categories.end();
270            for (begin = m_active_categories.begin(); begin != end; begin++)
271            {
272                lldb::TypeCategoryImplSP category = *begin;
273                ConstString type = ConstString(category->GetName());
274                if (!callback(param, category))
275                    break;
276            }
277        }
278
279        // loop through disabled categories in just any order
280        {
281            MapIterator pos, end = m_map.end();
282            for (pos = m_map.begin(); pos != end; pos++)
283            {
284                if (pos->second->IsEnabled())
285                    continue;
286                KeyType type = pos->first;
287                if (!callback(param, pos->second))
288                    break;
289            }
290        }
291    }
292}
293
294TypeCategoryImplSP
295TypeCategoryMap::GetAtIndex (uint32_t index)
296{
297    Mutex::Locker locker(m_map_mutex);
298
299    if (index < m_map.size())
300    {
301        MapIterator pos, end = m_map.end();
302        for (pos = m_map.begin(); pos != end; pos++)
303        {
304            if (index == 0)
305                return pos->second;
306            index--;
307        }
308    }
309
310    return TypeCategoryImplSP();
311}
312