1*c9af18a5SGreg Clayton //===-- CommandCompletions.cpp ----------------------------------*- C++ -*-===// 2*c9af18a5SGreg Clayton // 3*c9af18a5SGreg Clayton // The LLVM Compiler Infrastructure 4*c9af18a5SGreg Clayton // 5*c9af18a5SGreg Clayton // This file is distributed under the University of Illinois Open Source 6*c9af18a5SGreg Clayton // License. See LICENSE.TXT for details. 7*c9af18a5SGreg Clayton // 8*c9af18a5SGreg Clayton //===----------------------------------------------------------------------===// 9*c9af18a5SGreg Clayton 10*c9af18a5SGreg Clayton 11*c9af18a5SGreg Clayton // C Includes 12*c9af18a5SGreg Clayton // C++ Includes 13*c9af18a5SGreg Clayton // Other libraries and framework includes 14*c9af18a5SGreg Clayton // Project includes 15*c9af18a5SGreg Clayton #include "lldb/Core/Args.h" 16*c9af18a5SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 17*c9af18a5SGreg Clayton #include "lldb/Core/FileSpecList.h" 18*c9af18a5SGreg Clayton #include "lldb/Target/Target.h" 19*c9af18a5SGreg Clayton #include "lldb/Interpreter/CommandCompletions.h" 20*c9af18a5SGreg Clayton 21*c9af18a5SGreg Clayton 22*c9af18a5SGreg Clayton using namespace lldb_private; 23*c9af18a5SGreg Clayton 24*c9af18a5SGreg Clayton CommandCompletions::CommonCompletionElement 25*c9af18a5SGreg Clayton CommandCompletions::g_common_completions[] = 26*c9af18a5SGreg Clayton { 27*c9af18a5SGreg Clayton {eCustomCompletion, NULL}, 28*c9af18a5SGreg Clayton {eSourceFileCompletion, CommandCompletions::SourceFiles}, 29*c9af18a5SGreg Clayton {eDiskFileCompletion, NULL}, 30*c9af18a5SGreg Clayton {eSymbolCompletion, CommandCompletions::Symbols}, 31*c9af18a5SGreg Clayton {eModuleCompletion, CommandCompletions::Modules}, 32*c9af18a5SGreg Clayton {eNoCompletion, NULL} // This one has to be last in the list. 33*c9af18a5SGreg Clayton }; 34*c9af18a5SGreg Clayton 35*c9af18a5SGreg Clayton bool 36*c9af18a5SGreg Clayton CommandCompletions::InvokeCommonCompletionCallbacks (uint32_t completion_mask, 37*c9af18a5SGreg Clayton const char *completion_str, 38*c9af18a5SGreg Clayton int match_start_point, 39*c9af18a5SGreg Clayton int max_return_elements, 40*c9af18a5SGreg Clayton lldb_private::CommandInterpreter *interpreter, 41*c9af18a5SGreg Clayton SearchFilter *searcher, 42*c9af18a5SGreg Clayton lldb_private::StringList &matches) 43*c9af18a5SGreg Clayton { 44*c9af18a5SGreg Clayton bool handled = false; 45*c9af18a5SGreg Clayton 46*c9af18a5SGreg Clayton if (completion_mask & eCustomCompletion) 47*c9af18a5SGreg Clayton return false; 48*c9af18a5SGreg Clayton 49*c9af18a5SGreg Clayton for (int i = 0; ; i++) 50*c9af18a5SGreg Clayton { 51*c9af18a5SGreg Clayton if (g_common_completions[i].type == eNoCompletion) 52*c9af18a5SGreg Clayton break; 53*c9af18a5SGreg Clayton else if ((g_common_completions[i].type & completion_mask) == g_common_completions[i].type 54*c9af18a5SGreg Clayton && g_common_completions[i].callback != NULL) 55*c9af18a5SGreg Clayton { 56*c9af18a5SGreg Clayton handled = true; 57*c9af18a5SGreg Clayton g_common_completions[i].callback (completion_str, 58*c9af18a5SGreg Clayton match_start_point, 59*c9af18a5SGreg Clayton max_return_elements, 60*c9af18a5SGreg Clayton interpreter, 61*c9af18a5SGreg Clayton searcher, 62*c9af18a5SGreg Clayton matches); 63*c9af18a5SGreg Clayton } 64*c9af18a5SGreg Clayton } 65*c9af18a5SGreg Clayton return handled; 66*c9af18a5SGreg Clayton } 67*c9af18a5SGreg Clayton 68*c9af18a5SGreg Clayton int 69*c9af18a5SGreg Clayton CommandCompletions::SourceFiles (const char *partial_file_name, 70*c9af18a5SGreg Clayton int match_start_point, 71*c9af18a5SGreg Clayton int max_return_elements, 72*c9af18a5SGreg Clayton lldb_private::CommandInterpreter *interpreter, 73*c9af18a5SGreg Clayton SearchFilter *searcher, 74*c9af18a5SGreg Clayton lldb_private::StringList &matches) 75*c9af18a5SGreg Clayton { 76*c9af18a5SGreg Clayton // Find some way to switch "include support files..." 77*c9af18a5SGreg Clayton SourceFileCompleter completer (false, partial_file_name, match_start_point, max_return_elements, interpreter, 78*c9af18a5SGreg Clayton matches); 79*c9af18a5SGreg Clayton 80*c9af18a5SGreg Clayton if (searcher == NULL) 81*c9af18a5SGreg Clayton { 82*c9af18a5SGreg Clayton lldb::TargetSP target_sp = interpreter->Context()->GetTarget()->GetSP(); 83*c9af18a5SGreg Clayton SearchFilter null_searcher (target_sp); 84*c9af18a5SGreg Clayton completer.DoCompletion (&null_searcher); 85*c9af18a5SGreg Clayton } 86*c9af18a5SGreg Clayton else 87*c9af18a5SGreg Clayton { 88*c9af18a5SGreg Clayton completer.DoCompletion (searcher); 89*c9af18a5SGreg Clayton } 90*c9af18a5SGreg Clayton return matches.GetSize(); 91*c9af18a5SGreg Clayton } 92*c9af18a5SGreg Clayton 93*c9af18a5SGreg Clayton int 94*c9af18a5SGreg Clayton CommandCompletions::Modules (const char *partial_file_name, 95*c9af18a5SGreg Clayton int match_start_point, 96*c9af18a5SGreg Clayton int max_return_elements, 97*c9af18a5SGreg Clayton lldb_private::CommandInterpreter *interpreter, 98*c9af18a5SGreg Clayton SearchFilter *searcher, 99*c9af18a5SGreg Clayton lldb_private::StringList &matches) 100*c9af18a5SGreg Clayton { 101*c9af18a5SGreg Clayton ModuleCompleter completer(partial_file_name, match_start_point, max_return_elements, interpreter, matches); 102*c9af18a5SGreg Clayton 103*c9af18a5SGreg Clayton if (searcher == NULL) 104*c9af18a5SGreg Clayton { 105*c9af18a5SGreg Clayton lldb::TargetSP target_sp = interpreter->Context()->GetTarget()->GetSP(); 106*c9af18a5SGreg Clayton SearchFilter null_searcher (target_sp); 107*c9af18a5SGreg Clayton completer.DoCompletion (&null_searcher); 108*c9af18a5SGreg Clayton } 109*c9af18a5SGreg Clayton else 110*c9af18a5SGreg Clayton { 111*c9af18a5SGreg Clayton completer.DoCompletion (searcher); 112*c9af18a5SGreg Clayton } 113*c9af18a5SGreg Clayton return matches.GetSize(); 114*c9af18a5SGreg Clayton } 115*c9af18a5SGreg Clayton 116*c9af18a5SGreg Clayton int 117*c9af18a5SGreg Clayton CommandCompletions::Symbols (const char *partial_file_name, 118*c9af18a5SGreg Clayton int match_start_point, 119*c9af18a5SGreg Clayton int max_return_elements, 120*c9af18a5SGreg Clayton lldb_private::CommandInterpreter *interpreter, 121*c9af18a5SGreg Clayton SearchFilter *searcher, 122*c9af18a5SGreg Clayton lldb_private::StringList &matches) 123*c9af18a5SGreg Clayton { 124*c9af18a5SGreg Clayton SymbolCompleter completer(partial_file_name, match_start_point, max_return_elements, interpreter, matches); 125*c9af18a5SGreg Clayton 126*c9af18a5SGreg Clayton if (searcher == NULL) 127*c9af18a5SGreg Clayton { 128*c9af18a5SGreg Clayton lldb::TargetSP target_sp = interpreter->Context()->GetTarget()->GetSP(); 129*c9af18a5SGreg Clayton SearchFilter null_searcher (target_sp); 130*c9af18a5SGreg Clayton completer.DoCompletion (&null_searcher); 131*c9af18a5SGreg Clayton } 132*c9af18a5SGreg Clayton else 133*c9af18a5SGreg Clayton { 134*c9af18a5SGreg Clayton completer.DoCompletion (searcher); 135*c9af18a5SGreg Clayton } 136*c9af18a5SGreg Clayton return matches.GetSize(); 137*c9af18a5SGreg Clayton } 138*c9af18a5SGreg Clayton 139*c9af18a5SGreg Clayton CommandCompletions::Completer::Completer ( 140*c9af18a5SGreg Clayton const char *completion_str, 141*c9af18a5SGreg Clayton int match_start_point, 142*c9af18a5SGreg Clayton int max_return_elements, 143*c9af18a5SGreg Clayton CommandInterpreter *interpreter, 144*c9af18a5SGreg Clayton StringList &matches 145*c9af18a5SGreg Clayton ) : 146*c9af18a5SGreg Clayton m_completion_str (completion_str), 147*c9af18a5SGreg Clayton m_match_start_point (match_start_point), 148*c9af18a5SGreg Clayton m_max_return_elements (max_return_elements), 149*c9af18a5SGreg Clayton m_interpreter (interpreter), 150*c9af18a5SGreg Clayton m_matches (matches) 151*c9af18a5SGreg Clayton { 152*c9af18a5SGreg Clayton } 153*c9af18a5SGreg Clayton 154*c9af18a5SGreg Clayton CommandCompletions::Completer::~Completer () 155*c9af18a5SGreg Clayton { 156*c9af18a5SGreg Clayton 157*c9af18a5SGreg Clayton } 158*c9af18a5SGreg Clayton 159*c9af18a5SGreg Clayton //---------------------------------------------------------------------- 160*c9af18a5SGreg Clayton // SourceFileCompleter 161*c9af18a5SGreg Clayton //---------------------------------------------------------------------- 162*c9af18a5SGreg Clayton 163*c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::SourceFileCompleter ( 164*c9af18a5SGreg Clayton bool include_support_files, 165*c9af18a5SGreg Clayton const char *completion_str, 166*c9af18a5SGreg Clayton int match_start_point, 167*c9af18a5SGreg Clayton int max_return_elements, 168*c9af18a5SGreg Clayton CommandInterpreter *interpreter, 169*c9af18a5SGreg Clayton StringList &matches 170*c9af18a5SGreg Clayton ) : 171*c9af18a5SGreg Clayton CommandCompletions::Completer (completion_str, match_start_point, max_return_elements, interpreter, matches), 172*c9af18a5SGreg Clayton m_include_support_files (include_support_files), 173*c9af18a5SGreg Clayton m_matching_files() 174*c9af18a5SGreg Clayton { 175*c9af18a5SGreg Clayton FileSpec partial_spec (m_completion_str.c_str()); 176*c9af18a5SGreg Clayton m_file_name = partial_spec.GetFilename().GetCString(); 177*c9af18a5SGreg Clayton m_dir_name = partial_spec.GetDirectory().GetCString(); 178*c9af18a5SGreg Clayton } 179*c9af18a5SGreg Clayton 180*c9af18a5SGreg Clayton Searcher::Depth 181*c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::GetDepth() 182*c9af18a5SGreg Clayton { 183*c9af18a5SGreg Clayton return eDepthCompUnit; 184*c9af18a5SGreg Clayton } 185*c9af18a5SGreg Clayton 186*c9af18a5SGreg Clayton Searcher::CallbackReturn 187*c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::SearchCallback ( 188*c9af18a5SGreg Clayton SearchFilter &filter, 189*c9af18a5SGreg Clayton SymbolContext &context, 190*c9af18a5SGreg Clayton Address *addr, 191*c9af18a5SGreg Clayton bool complete 192*c9af18a5SGreg Clayton ) 193*c9af18a5SGreg Clayton { 194*c9af18a5SGreg Clayton if (context.comp_unit != NULL) 195*c9af18a5SGreg Clayton { 196*c9af18a5SGreg Clayton if (m_include_support_files) 197*c9af18a5SGreg Clayton { 198*c9af18a5SGreg Clayton FileSpecList supporting_files = context.comp_unit->GetSupportFiles(); 199*c9af18a5SGreg Clayton for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++) 200*c9af18a5SGreg Clayton { 201*c9af18a5SGreg Clayton const FileSpec &sfile_spec = supporting_files.GetFileSpecAtIndex(sfiles); 202*c9af18a5SGreg Clayton const char *sfile_file_name = sfile_spec.GetFilename().GetCString(); 203*c9af18a5SGreg Clayton const char *sfile_dir_name = sfile_spec.GetFilename().GetCString(); 204*c9af18a5SGreg Clayton bool match = false; 205*c9af18a5SGreg Clayton if (m_file_name && sfile_file_name 206*c9af18a5SGreg Clayton && strstr (sfile_file_name, m_file_name) == sfile_file_name) 207*c9af18a5SGreg Clayton match = true; 208*c9af18a5SGreg Clayton if (match && m_dir_name && sfile_dir_name 209*c9af18a5SGreg Clayton && strstr (sfile_dir_name, m_dir_name) != sfile_dir_name) 210*c9af18a5SGreg Clayton match = false; 211*c9af18a5SGreg Clayton 212*c9af18a5SGreg Clayton if (match) 213*c9af18a5SGreg Clayton { 214*c9af18a5SGreg Clayton m_matching_files.AppendIfUnique(sfile_spec); 215*c9af18a5SGreg Clayton } 216*c9af18a5SGreg Clayton } 217*c9af18a5SGreg Clayton 218*c9af18a5SGreg Clayton } 219*c9af18a5SGreg Clayton else 220*c9af18a5SGreg Clayton { 221*c9af18a5SGreg Clayton const char *cur_file_name = context.comp_unit->GetFilename().GetCString(); 222*c9af18a5SGreg Clayton const char *cur_dir_name = context.comp_unit->GetDirectory().GetCString(); 223*c9af18a5SGreg Clayton 224*c9af18a5SGreg Clayton bool match = false; 225*c9af18a5SGreg Clayton if (m_file_name && cur_file_name 226*c9af18a5SGreg Clayton && strstr (cur_file_name, m_file_name) == cur_file_name) 227*c9af18a5SGreg Clayton match = true; 228*c9af18a5SGreg Clayton 229*c9af18a5SGreg Clayton if (match && m_dir_name && cur_dir_name 230*c9af18a5SGreg Clayton && strstr (cur_dir_name, m_dir_name) != cur_dir_name) 231*c9af18a5SGreg Clayton match = false; 232*c9af18a5SGreg Clayton 233*c9af18a5SGreg Clayton if (match) 234*c9af18a5SGreg Clayton { 235*c9af18a5SGreg Clayton m_matching_files.AppendIfUnique(context.comp_unit); 236*c9af18a5SGreg Clayton } 237*c9af18a5SGreg Clayton } 238*c9af18a5SGreg Clayton } 239*c9af18a5SGreg Clayton return Searcher::eCallbackReturnContinue; 240*c9af18a5SGreg Clayton } 241*c9af18a5SGreg Clayton 242*c9af18a5SGreg Clayton size_t 243*c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::DoCompletion (SearchFilter *filter) 244*c9af18a5SGreg Clayton { 245*c9af18a5SGreg Clayton filter->Search (*this); 246*c9af18a5SGreg Clayton // Now convert the filelist to completions: 247*c9af18a5SGreg Clayton for (size_t i = 0; i < m_matching_files.GetSize(); i++) 248*c9af18a5SGreg Clayton { 249*c9af18a5SGreg Clayton m_matches.AppendString (m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); 250*c9af18a5SGreg Clayton } 251*c9af18a5SGreg Clayton return m_matches.GetSize(); 252*c9af18a5SGreg Clayton 253*c9af18a5SGreg Clayton } 254*c9af18a5SGreg Clayton 255*c9af18a5SGreg Clayton //---------------------------------------------------------------------- 256*c9af18a5SGreg Clayton // SymbolCompleter 257*c9af18a5SGreg Clayton //---------------------------------------------------------------------- 258*c9af18a5SGreg Clayton 259*c9af18a5SGreg Clayton static bool 260*c9af18a5SGreg Clayton regex_chars (const char comp) 261*c9af18a5SGreg Clayton { 262*c9af18a5SGreg Clayton if (comp == '[' || comp == ']' || comp == '(' || comp == ')') 263*c9af18a5SGreg Clayton return true; 264*c9af18a5SGreg Clayton else 265*c9af18a5SGreg Clayton return false; 266*c9af18a5SGreg Clayton } 267*c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::SymbolCompleter ( 268*c9af18a5SGreg Clayton const char *completion_str, 269*c9af18a5SGreg Clayton int match_start_point, 270*c9af18a5SGreg Clayton int max_return_elements, 271*c9af18a5SGreg Clayton CommandInterpreter *interpreter, 272*c9af18a5SGreg Clayton StringList &matches 273*c9af18a5SGreg Clayton ) : 274*c9af18a5SGreg Clayton CommandCompletions::Completer (completion_str, match_start_point, max_return_elements, interpreter, matches) 275*c9af18a5SGreg Clayton { 276*c9af18a5SGreg Clayton std::string regex_str ("^"); 277*c9af18a5SGreg Clayton regex_str.append(completion_str); 278*c9af18a5SGreg Clayton regex_str.append(".*"); 279*c9af18a5SGreg Clayton std::string::iterator pos; 280*c9af18a5SGreg Clayton 281*c9af18a5SGreg Clayton pos = find_if(regex_str.begin(), regex_str.end(), regex_chars); 282*c9af18a5SGreg Clayton while (pos < regex_str.end()) { 283*c9af18a5SGreg Clayton pos = regex_str.insert(pos, '\\'); 284*c9af18a5SGreg Clayton pos += 2; 285*c9af18a5SGreg Clayton pos = find_if(pos, regex_str.end(), regex_chars); 286*c9af18a5SGreg Clayton } 287*c9af18a5SGreg Clayton m_regex.Compile(regex_str.c_str()); 288*c9af18a5SGreg Clayton } 289*c9af18a5SGreg Clayton 290*c9af18a5SGreg Clayton Searcher::Depth 291*c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::GetDepth() 292*c9af18a5SGreg Clayton { 293*c9af18a5SGreg Clayton return eDepthModule; 294*c9af18a5SGreg Clayton } 295*c9af18a5SGreg Clayton 296*c9af18a5SGreg Clayton Searcher::CallbackReturn 297*c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::SearchCallback ( 298*c9af18a5SGreg Clayton SearchFilter &filter, 299*c9af18a5SGreg Clayton SymbolContext &context, 300*c9af18a5SGreg Clayton Address *addr, 301*c9af18a5SGreg Clayton bool complete 302*c9af18a5SGreg Clayton ) 303*c9af18a5SGreg Clayton { 304*c9af18a5SGreg Clayton SymbolContextList func_list; 305*c9af18a5SGreg Clayton SymbolContextList sym_list; 306*c9af18a5SGreg Clayton 307*c9af18a5SGreg Clayton if (context.module_sp != NULL) 308*c9af18a5SGreg Clayton { 309*c9af18a5SGreg Clayton if (context.module_sp) 310*c9af18a5SGreg Clayton { 311*c9af18a5SGreg Clayton context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, lldb::eSymbolTypeCode, sym_list); 312*c9af18a5SGreg Clayton context.module_sp->FindFunctions (m_regex, true, func_list); 313*c9af18a5SGreg Clayton } 314*c9af18a5SGreg Clayton 315*c9af18a5SGreg Clayton SymbolContext sc; 316*c9af18a5SGreg Clayton // Now add the functions & symbols to the list - only add if unique: 317*c9af18a5SGreg Clayton for (int i = 0; i < func_list.GetSize(); i++) 318*c9af18a5SGreg Clayton { 319*c9af18a5SGreg Clayton if (func_list.GetContextAtIndex(i, sc)) 320*c9af18a5SGreg Clayton { 321*c9af18a5SGreg Clayton if (sc.function) 322*c9af18a5SGreg Clayton { 323*c9af18a5SGreg Clayton m_match_set.insert (sc.function->GetMangled().GetDemangledName()); 324*c9af18a5SGreg Clayton } 325*c9af18a5SGreg Clayton } 326*c9af18a5SGreg Clayton } 327*c9af18a5SGreg Clayton 328*c9af18a5SGreg Clayton for (int i = 0; i < sym_list.GetSize(); i++) 329*c9af18a5SGreg Clayton { 330*c9af18a5SGreg Clayton if (sym_list.GetContextAtIndex(i, sc)) 331*c9af18a5SGreg Clayton { 332*c9af18a5SGreg Clayton if (sc.symbol && sc.symbol->GetAddressRangePtr()) 333*c9af18a5SGreg Clayton { 334*c9af18a5SGreg Clayton m_match_set.insert (sc.symbol->GetMangled().GetDemangledName()); 335*c9af18a5SGreg Clayton } 336*c9af18a5SGreg Clayton } 337*c9af18a5SGreg Clayton } 338*c9af18a5SGreg Clayton } 339*c9af18a5SGreg Clayton return Searcher::eCallbackReturnContinue; 340*c9af18a5SGreg Clayton } 341*c9af18a5SGreg Clayton 342*c9af18a5SGreg Clayton size_t 343*c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::DoCompletion (SearchFilter *filter) 344*c9af18a5SGreg Clayton { 345*c9af18a5SGreg Clayton filter->Search (*this); 346*c9af18a5SGreg Clayton collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); 347*c9af18a5SGreg Clayton for (pos = m_match_set.begin(); pos != end; pos++) 348*c9af18a5SGreg Clayton m_matches.AppendString((*pos).GetCString()); 349*c9af18a5SGreg Clayton 350*c9af18a5SGreg Clayton return m_matches.GetSize(); 351*c9af18a5SGreg Clayton } 352*c9af18a5SGreg Clayton 353*c9af18a5SGreg Clayton //---------------------------------------------------------------------- 354*c9af18a5SGreg Clayton // ModuleCompleter 355*c9af18a5SGreg Clayton //---------------------------------------------------------------------- 356*c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::ModuleCompleter ( 357*c9af18a5SGreg Clayton const char *completion_str, 358*c9af18a5SGreg Clayton int match_start_point, 359*c9af18a5SGreg Clayton int max_return_elements, 360*c9af18a5SGreg Clayton CommandInterpreter *interpreter, 361*c9af18a5SGreg Clayton StringList &matches 362*c9af18a5SGreg Clayton ) : 363*c9af18a5SGreg Clayton CommandCompletions::Completer (completion_str, match_start_point, max_return_elements, interpreter, matches) 364*c9af18a5SGreg Clayton { 365*c9af18a5SGreg Clayton FileSpec partial_spec (m_completion_str.c_str()); 366*c9af18a5SGreg Clayton m_file_name = partial_spec.GetFilename().GetCString(); 367*c9af18a5SGreg Clayton m_dir_name = partial_spec.GetDirectory().GetCString(); 368*c9af18a5SGreg Clayton } 369*c9af18a5SGreg Clayton 370*c9af18a5SGreg Clayton Searcher::Depth 371*c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::GetDepth() 372*c9af18a5SGreg Clayton { 373*c9af18a5SGreg Clayton return eDepthModule; 374*c9af18a5SGreg Clayton } 375*c9af18a5SGreg Clayton 376*c9af18a5SGreg Clayton Searcher::CallbackReturn 377*c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::SearchCallback ( 378*c9af18a5SGreg Clayton SearchFilter &filter, 379*c9af18a5SGreg Clayton SymbolContext &context, 380*c9af18a5SGreg Clayton Address *addr, 381*c9af18a5SGreg Clayton bool complete 382*c9af18a5SGreg Clayton ) 383*c9af18a5SGreg Clayton { 384*c9af18a5SGreg Clayton if (context.module_sp != NULL) 385*c9af18a5SGreg Clayton { 386*c9af18a5SGreg Clayton const char *cur_file_name = context.module_sp->GetFileSpec().GetFilename().GetCString(); 387*c9af18a5SGreg Clayton const char *cur_dir_name = context.module_sp->GetFileSpec().GetDirectory().GetCString(); 388*c9af18a5SGreg Clayton 389*c9af18a5SGreg Clayton bool match = false; 390*c9af18a5SGreg Clayton if (m_file_name && cur_file_name 391*c9af18a5SGreg Clayton && strstr (cur_file_name, m_file_name) == cur_file_name) 392*c9af18a5SGreg Clayton match = true; 393*c9af18a5SGreg Clayton 394*c9af18a5SGreg Clayton if (match && m_dir_name && cur_dir_name 395*c9af18a5SGreg Clayton && strstr (cur_dir_name, m_dir_name) != cur_dir_name) 396*c9af18a5SGreg Clayton match = false; 397*c9af18a5SGreg Clayton 398*c9af18a5SGreg Clayton if (match) 399*c9af18a5SGreg Clayton { 400*c9af18a5SGreg Clayton m_matches.AppendString (cur_file_name); 401*c9af18a5SGreg Clayton } 402*c9af18a5SGreg Clayton } 403*c9af18a5SGreg Clayton return Searcher::eCallbackReturnContinue; 404*c9af18a5SGreg Clayton } 405*c9af18a5SGreg Clayton 406*c9af18a5SGreg Clayton size_t 407*c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::DoCompletion (SearchFilter *filter) 408*c9af18a5SGreg Clayton { 409*c9af18a5SGreg Clayton filter->Search (*this); 410*c9af18a5SGreg Clayton return m_matches.GetSize(); 411*c9af18a5SGreg Clayton } 412*c9af18a5SGreg Clayton 413*c9af18a5SGreg Clayton 414*c9af18a5SGreg Clayton 415