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