TypeCategoryMap.cpp revision 280031
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::EnableAllCategories () 124{ 125 Mutex::Locker locker(m_map_mutex); 126 std::vector<ValueSP> sorted_categories(m_map.size(), ValueSP()); 127 MapType::iterator iter = m_map.begin(), end = m_map.end(); 128 for (; iter != end; ++iter) 129 { 130 if (iter->second->IsEnabled()) 131 continue; 132 auto pos = iter->second->GetLastEnabledPosition(); 133 if (pos >= sorted_categories.size()) 134 { 135 auto iter = std::find_if(sorted_categories.begin(), 136 sorted_categories.end(), 137 [] (const ValueSP& sp) -> bool { 138 return sp.get() == nullptr; 139 }); 140 pos = std::distance(sorted_categories.begin(), iter); 141 } 142 sorted_categories.at(pos) = iter->second; 143 } 144 decltype(sorted_categories)::iterator viter = sorted_categories.begin(), vend = sorted_categories.end(); 145 for (; viter != vend; viter++) 146 if (viter->get()) 147 Enable(*viter, Last); 148} 149 150void 151TypeCategoryMap::DisableAllCategories () 152{ 153 Mutex::Locker locker(m_map_mutex); 154 Position p = First; 155 for (; false == m_active_categories.empty(); p++) 156 { 157 m_active_categories.front()->SetEnabledPosition(p); 158 Disable(m_active_categories.front()); 159 } 160} 161 162void 163TypeCategoryMap::Clear () 164{ 165 Mutex::Locker locker(m_map_mutex); 166 m_map.clear(); 167 m_active_categories.clear(); 168 if (listener) 169 listener->Changed(); 170} 171 172bool 173TypeCategoryMap::Get (KeyType name, ValueSP& entry) 174{ 175 Mutex::Locker locker(m_map_mutex); 176 MapIterator iter = m_map.find(name); 177 if (iter == m_map.end()) 178 return false; 179 entry = iter->second; 180 return true; 181} 182 183bool 184TypeCategoryMap::Get (uint32_t pos, ValueSP& entry) 185{ 186 Mutex::Locker locker(m_map_mutex); 187 MapIterator iter = m_map.begin(); 188 MapIterator end = m_map.end(); 189 while (pos > 0) 190 { 191 iter++; 192 pos--; 193 if (iter == end) 194 return false; 195 } 196 entry = iter->second; 197 return false; 198} 199 200bool 201TypeCategoryMap::AnyMatches (ConstString type_name, 202 TypeCategoryImpl::FormatCategoryItems items, 203 bool only_enabled, 204 const char** matching_category, 205 TypeCategoryImpl::FormatCategoryItems* matching_type) 206{ 207 Mutex::Locker locker(m_map_mutex); 208 209 MapIterator pos, end = m_map.end(); 210 for (pos = m_map.begin(); pos != end; pos++) 211 { 212 if (pos->second->AnyMatches(type_name, 213 items, 214 only_enabled, 215 matching_category, 216 matching_type)) 217 return true; 218 } 219 return false; 220} 221 222lldb::TypeFormatImplSP 223TypeCategoryMap::GetFormat (ValueObject& valobj, 224 lldb::DynamicValueType use_dynamic) 225{ 226 Mutex::Locker locker(m_map_mutex); 227 228 uint32_t reason_why; 229 ActiveCategoriesIterator begin, end = m_active_categories.end(); 230 231 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 232 233 FormattersMatchVector matches = FormatManager::GetPossibleMatches(valobj, use_dynamic); 234 235 for (begin = m_active_categories.begin(); begin != end; begin++) 236 { 237 lldb::TypeCategoryImplSP category_sp = *begin; 238 lldb::TypeFormatImplSP current_format; 239 if (log) 240 log->Printf("\n[TypeCategoryMap::GetFormat] Trying to use category %s", category_sp->GetName()); 241 if (!category_sp->Get(valobj, matches, current_format, &reason_why)) 242 continue; 243 return current_format; 244 } 245 if (log) 246 log->Printf("[TypeCategoryMap::GetFormat] nothing found - returning empty SP"); 247 return lldb::TypeFormatImplSP(); 248} 249 250lldb::TypeSummaryImplSP 251TypeCategoryMap::GetSummaryFormat (ValueObject& valobj, 252 lldb::DynamicValueType use_dynamic) 253{ 254 Mutex::Locker locker(m_map_mutex); 255 256 uint32_t reason_why; 257 ActiveCategoriesIterator begin, end = m_active_categories.end(); 258 259 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 260 261 FormattersMatchVector matches = FormatManager::GetPossibleMatches(valobj, use_dynamic); 262 263 for (begin = m_active_categories.begin(); begin != end; begin++) 264 { 265 lldb::TypeCategoryImplSP category_sp = *begin; 266 lldb::TypeSummaryImplSP current_format; 267 if (log) 268 log->Printf("\n[CategoryMap::GetSummaryFormat] Trying to use category %s", category_sp->GetName()); 269 if (!category_sp->Get(valobj, matches, current_format, &reason_why)) 270 continue; 271 return current_format; 272 } 273 if (log) 274 log->Printf("[CategoryMap::GetSummaryFormat] nothing found - returning empty SP"); 275 return lldb::TypeSummaryImplSP(); 276} 277 278#ifndef LLDB_DISABLE_PYTHON 279lldb::SyntheticChildrenSP 280TypeCategoryMap::GetSyntheticChildren (ValueObject& valobj, 281 lldb::DynamicValueType use_dynamic) 282{ 283 Mutex::Locker locker(m_map_mutex); 284 285 uint32_t reason_why; 286 287 ActiveCategoriesIterator begin, end = m_active_categories.end(); 288 289 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 290 291 FormattersMatchVector matches = FormatManager::GetPossibleMatches(valobj, use_dynamic); 292 293 for (begin = m_active_categories.begin(); begin != end; begin++) 294 { 295 lldb::TypeCategoryImplSP category_sp = *begin; 296 lldb::SyntheticChildrenSP current_format; 297 if (log) 298 log->Printf("\n[CategoryMap::GetSyntheticChildren] Trying to use category %s", category_sp->GetName()); 299 if (!category_sp->Get(valobj, matches, current_format, &reason_why)) 300 continue; 301 return current_format; 302 } 303 if (log) 304 log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning empty SP"); 305 return lldb::SyntheticChildrenSP(); 306} 307#endif 308 309lldb::TypeValidatorImplSP 310TypeCategoryMap::GetValidator (ValueObject& valobj, 311 lldb::DynamicValueType use_dynamic) 312{ 313 Mutex::Locker locker(m_map_mutex); 314 315 uint32_t reason_why; 316 ActiveCategoriesIterator begin, end = m_active_categories.end(); 317 318 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); 319 320 FormattersMatchVector matches = FormatManager::GetPossibleMatches(valobj, use_dynamic); 321 322 for (begin = m_active_categories.begin(); begin != end; begin++) 323 { 324 lldb::TypeCategoryImplSP category_sp = *begin; 325 lldb::TypeValidatorImplSP current_format; 326 if (log) 327 log->Printf("\n[CategoryMap::GetValidator] Trying to use category %s", category_sp->GetName()); 328 if (!category_sp->Get(valobj, matches, current_format, &reason_why)) 329 continue; 330 return current_format; 331 } 332 if (log) 333 log->Printf("[CategoryMap::GetValidator] nothing found - returning empty SP"); 334 return lldb::TypeValidatorImplSP(); 335} 336 337void 338TypeCategoryMap::LoopThrough(CallbackType callback, void* param) 339{ 340 if (callback) 341 { 342 Mutex::Locker locker(m_map_mutex); 343 344 // loop through enabled categories in respective order 345 { 346 ActiveCategoriesIterator begin, end = m_active_categories.end(); 347 for (begin = m_active_categories.begin(); begin != end; begin++) 348 { 349 lldb::TypeCategoryImplSP category = *begin; 350 ConstString type = ConstString(category->GetName()); 351 if (!callback(param, category)) 352 break; 353 } 354 } 355 356 // loop through disabled categories in just any order 357 { 358 MapIterator pos, end = m_map.end(); 359 for (pos = m_map.begin(); pos != end; pos++) 360 { 361 if (pos->second->IsEnabled()) 362 continue; 363 KeyType type = pos->first; 364 if (!callback(param, pos->second)) 365 break; 366 } 367 } 368 } 369} 370 371TypeCategoryImplSP 372TypeCategoryMap::GetAtIndex (uint32_t index) 373{ 374 Mutex::Locker locker(m_map_mutex); 375 376 if (index < m_map.size()) 377 { 378 MapIterator pos, end = m_map.end(); 379 for (pos = m_map.begin(); pos != end; pos++) 380 { 381 if (index == 0) 382 return pos->second; 383 index--; 384 } 385 } 386 387 return TypeCategoryImplSP(); 388} 389