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
19 using namespace lldb;
20 using namespace lldb_private;
21
TypeCategoryMap(IFormatChangeListener * lst)22 TypeCategoryMap::TypeCategoryMap (IFormatChangeListener* lst) :
23 m_map_mutex(Mutex::eMutexTypeRecursive),
24 listener(lst),
25 m_map(),
26 m_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
34 void
Add(KeyType name,const ValueSP & entry)35 TypeCategoryMap::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
43 bool
Delete(KeyType name)44 TypeCategoryMap::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
57 bool
Enable(KeyType category_name,Position pos)58 TypeCategoryMap::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
67 bool
Disable(KeyType category_name)68 TypeCategoryMap::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
77 bool
Enable(ValueSP category,Position pos)78 TypeCategoryMap::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
106 bool
Disable(ValueSP category)107 TypeCategoryMap::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
119 void
Clear()120 TypeCategoryMap::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
129 bool
Get(KeyType name,ValueSP & entry)130 TypeCategoryMap::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
140 bool
Get(uint32_t pos,ValueSP & entry)141 TypeCategoryMap::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
157 bool
AnyMatches(ConstString type_name,TypeCategoryImpl::FormatCategoryItems items,bool only_enabled,const char ** matching_category,TypeCategoryImpl::FormatCategoryItems * matching_type)158 TypeCategoryMap::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
179 lldb::TypeSummaryImplSP
GetSummaryFormat(ValueObject & valobj,lldb::DynamicValueType use_dynamic)180 TypeCategoryMap::GetSummaryFormat (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::TypeSummaryImplSP current_format;
194 if (log)
195 log->Printf("\n[CategoryMap::GetSummaryFormat] 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("[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
202 return lldb::TypeSummaryImplSP();
203 }
204
205 #ifndef LLDB_DISABLE_PYTHON
206 lldb::SyntheticChildrenSP
GetSyntheticChildren(ValueObject & valobj,lldb::DynamicValueType use_dynamic)207 TypeCategoryMap::GetSyntheticChildren (ValueObject& valobj,
208 lldb::DynamicValueType use_dynamic)
209 {
210 Mutex::Locker locker(m_map_mutex);
211
212 uint32_t reason_why;
213
214 ActiveCategoriesIterator begin, end = m_active_categories.end();
215
216 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
217
218 for (begin = m_active_categories.begin(); begin != end; begin++)
219 {
220 lldb::TypeCategoryImplSP category_sp = *begin;
221 lldb::SyntheticChildrenSP current_format;
222 if (log)
223 log->Printf("\n[CategoryMap::GetSyntheticChildren] Trying to use category %s", category_sp->GetName());
224 if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why))
225 continue;
226 return current_format;
227 }
228 if (log)
229 log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning empty SP");
230 return lldb::SyntheticChildrenSP();
231 }
232 #endif
233
234 void
LoopThrough(CallbackType callback,void * param)235 TypeCategoryMap::LoopThrough(CallbackType callback, void* param)
236 {
237 if (callback)
238 {
239 Mutex::Locker locker(m_map_mutex);
240
241 // loop through enabled categories in respective order
242 {
243 ActiveCategoriesIterator begin, end = m_active_categories.end();
244 for (begin = m_active_categories.begin(); begin != end; begin++)
245 {
246 lldb::TypeCategoryImplSP category = *begin;
247 ConstString type = ConstString(category->GetName());
248 if (!callback(param, category))
249 break;
250 }
251 }
252
253 // loop through disabled categories in just any order
254 {
255 MapIterator pos, end = m_map.end();
256 for (pos = m_map.begin(); pos != end; pos++)
257 {
258 if (pos->second->IsEnabled())
259 continue;
260 KeyType type = pos->first;
261 if (!callback(param, pos->second))
262 break;
263 }
264 }
265 }
266 }
267
268 TypeCategoryImplSP
GetAtIndex(uint32_t index)269 TypeCategoryMap::GetAtIndex (uint32_t index)
270 {
271 Mutex::Locker locker(m_map_mutex);
272
273 if (index < m_map.size())
274 {
275 MapIterator pos, end = m_map.end();
276 for (pos = m_map.begin(); pos != end; pos++)
277 {
278 if (index == 0)
279 return pos->second;
280 index--;
281 }
282 }
283
284 return TypeCategoryImplSP();
285 }
286