1c9af18a5SGreg Clayton //===-- CommandCompletions.cpp ----------------------------------*- C++ -*-===// 2c9af18a5SGreg Clayton // 3c9af18a5SGreg Clayton // The LLVM Compiler Infrastructure 4c9af18a5SGreg Clayton // 5c9af18a5SGreg Clayton // This file is distributed under the University of Illinois Open Source 6c9af18a5SGreg Clayton // License. See LICENSE.TXT for details. 7c9af18a5SGreg Clayton // 8c9af18a5SGreg Clayton //===----------------------------------------------------------------------===// 9c9af18a5SGreg Clayton 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 11c9af18a5SGreg Clayton 12c9af18a5SGreg Clayton // C Includes 13558ce124SJim Ingham #include <sys/stat.h> 14558ce124SJim Ingham #include <dirent.h> 15fd18426eSGreg Clayton #if defined(__APPLE__) || defined(__linux__) 167cc478b9SJim Ingham #include <pwd.h> 17fd18426eSGreg Clayton #endif 18558ce124SJim Ingham 19c9af18a5SGreg Clayton // C++ Includes 20c9af18a5SGreg Clayton // Other libraries and framework includes 21c9af18a5SGreg Clayton // Project includes 2253239f00SGreg Clayton #include "lldb/Host/FileSpec.h" 239b62fd2fSGreg Clayton #include "lldb/Core/FileSpecList.h" 24ab65b34fSGreg Clayton #include "lldb/Core/PluginManager.h" 251f746071SGreg Clayton #include "lldb/Core/Module.h" 269b62fd2fSGreg Clayton #include "lldb/Interpreter/Args.h" 279b62fd2fSGreg Clayton #include "lldb/Interpreter/CommandCompletions.h" 289b62fd2fSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 291f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h" 30*f21feadcSGreg Clayton #include "lldb/Symbol/Variable.h" 319b62fd2fSGreg Clayton #include "lldb/Target/Target.h" 329b62fd2fSGreg Clayton #include "lldb/Utility/CleanUp.h" 33c9af18a5SGreg Clayton 34c9af18a5SGreg Clayton using namespace lldb_private; 35c9af18a5SGreg Clayton 36c9af18a5SGreg Clayton CommandCompletions::CommonCompletionElement 37c9af18a5SGreg Clayton CommandCompletions::g_common_completions[] = 38c9af18a5SGreg Clayton { 39c9af18a5SGreg Clayton {eCustomCompletion, NULL}, 40c9af18a5SGreg Clayton {eSourceFileCompletion, CommandCompletions::SourceFiles}, 41558ce124SJim Ingham {eDiskFileCompletion, CommandCompletions::DiskFiles}, 42558ce124SJim Ingham {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories}, 43c9af18a5SGreg Clayton {eSymbolCompletion, CommandCompletions::Symbols}, 44c9af18a5SGreg Clayton {eModuleCompletion, CommandCompletions::Modules}, 453df9a8dfSCaroline Tice {eSettingsNameCompletion, CommandCompletions::SettingsNames}, 46ab65b34fSGreg Clayton {ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames}, 47ab65b34fSGreg Clayton {eArchitectureCompletion, CommandCompletions::ArchitectureNames}, 48*f21feadcSGreg Clayton {eVariablePathCompletion, CommandCompletions::VariablePath}, 49c9af18a5SGreg Clayton {eNoCompletion, NULL} // This one has to be last in the list. 50c9af18a5SGreg Clayton }; 51c9af18a5SGreg Clayton 52c9af18a5SGreg Clayton bool 536611103cSGreg Clayton CommandCompletions::InvokeCommonCompletionCallbacks 546611103cSGreg Clayton ( 556611103cSGreg Clayton CommandInterpreter &interpreter, 566611103cSGreg Clayton uint32_t completion_mask, 57c9af18a5SGreg Clayton const char *completion_str, 58c9af18a5SGreg Clayton int match_start_point, 59c9af18a5SGreg Clayton int max_return_elements, 60c9af18a5SGreg Clayton SearchFilter *searcher, 61558ce124SJim Ingham bool &word_complete, 626611103cSGreg Clayton StringList &matches 636611103cSGreg Clayton ) 64c9af18a5SGreg Clayton { 65c9af18a5SGreg Clayton bool handled = false; 66c9af18a5SGreg Clayton 67c9af18a5SGreg Clayton if (completion_mask & eCustomCompletion) 68c9af18a5SGreg Clayton return false; 69c9af18a5SGreg Clayton 70c9af18a5SGreg Clayton for (int i = 0; ; i++) 71c9af18a5SGreg Clayton { 72c9af18a5SGreg Clayton if (g_common_completions[i].type == eNoCompletion) 73c9af18a5SGreg Clayton break; 74c9af18a5SGreg Clayton else if ((g_common_completions[i].type & completion_mask) == g_common_completions[i].type 75c9af18a5SGreg Clayton && g_common_completions[i].callback != NULL) 76c9af18a5SGreg Clayton { 77c9af18a5SGreg Clayton handled = true; 786611103cSGreg Clayton g_common_completions[i].callback (interpreter, 796611103cSGreg Clayton completion_str, 80c9af18a5SGreg Clayton match_start_point, 81c9af18a5SGreg Clayton max_return_elements, 82c9af18a5SGreg Clayton searcher, 83558ce124SJim Ingham word_complete, 84c9af18a5SGreg Clayton matches); 85c9af18a5SGreg Clayton } 86c9af18a5SGreg Clayton } 87c9af18a5SGreg Clayton return handled; 88c9af18a5SGreg Clayton } 89c9af18a5SGreg Clayton 90c9af18a5SGreg Clayton int 916611103cSGreg Clayton CommandCompletions::SourceFiles 926611103cSGreg Clayton ( 936611103cSGreg Clayton CommandInterpreter &interpreter, 946611103cSGreg Clayton const char *partial_file_name, 95c9af18a5SGreg Clayton int match_start_point, 96c9af18a5SGreg Clayton int max_return_elements, 97c9af18a5SGreg Clayton SearchFilter *searcher, 98558ce124SJim Ingham bool &word_complete, 996611103cSGreg Clayton StringList &matches 1006611103cSGreg Clayton ) 101c9af18a5SGreg Clayton { 102558ce124SJim Ingham word_complete = true; 103c9af18a5SGreg Clayton // Find some way to switch "include support files..." 1046611103cSGreg Clayton SourceFileCompleter completer (interpreter, 1056611103cSGreg Clayton false, 1066611103cSGreg Clayton partial_file_name, 1076611103cSGreg Clayton match_start_point, 1086611103cSGreg Clayton max_return_elements, 109c9af18a5SGreg Clayton matches); 110c9af18a5SGreg Clayton 111c9af18a5SGreg Clayton if (searcher == NULL) 112c9af18a5SGreg Clayton { 1132976d00aSJim Ingham lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); 114c9af18a5SGreg Clayton SearchFilter null_searcher (target_sp); 115c9af18a5SGreg Clayton completer.DoCompletion (&null_searcher); 116c9af18a5SGreg Clayton } 117c9af18a5SGreg Clayton else 118c9af18a5SGreg Clayton { 119c9af18a5SGreg Clayton completer.DoCompletion (searcher); 120c9af18a5SGreg Clayton } 121c9af18a5SGreg Clayton return matches.GetSize(); 122c9af18a5SGreg Clayton } 123c9af18a5SGreg Clayton 124558ce124SJim Ingham static int 125558ce124SJim Ingham DiskFilesOrDirectories 126558ce124SJim Ingham ( 127558ce124SJim Ingham const char *partial_file_name, 128558ce124SJim Ingham bool only_directories, 129558ce124SJim Ingham bool &saw_directory, 130558ce124SJim Ingham StringList &matches 131558ce124SJim Ingham ) 132558ce124SJim Ingham { 133558ce124SJim Ingham // I'm going to use the "glob" function with GLOB_TILDE for user directory expansion. 134558ce124SJim Ingham // If it is not defined on your host system, you'll need to implement it yourself... 135558ce124SJim Ingham 136c7bece56SGreg Clayton size_t partial_name_len = strlen(partial_file_name); 137558ce124SJim Ingham 138558ce124SJim Ingham if (partial_name_len >= PATH_MAX) 139558ce124SJim Ingham return matches.GetSize(); 140558ce124SJim Ingham 141558ce124SJim Ingham // This copy of the string will be cut up into the directory part, and the remainder. end_ptr 142558ce124SJim Ingham // below will point to the place of the remainder in this string. Then when we've resolved the 143558ce124SJim Ingham // containing directory, and opened it, we'll read the directory contents and overwrite the 144558ce124SJim Ingham // partial_name_copy starting from end_ptr with each of the matches. Thus we will preserve 145558ce124SJim Ingham // the form the user originally typed. 146558ce124SJim Ingham 147558ce124SJim Ingham char partial_name_copy[PATH_MAX]; 148021b605dSBenjamin Kramer memcpy(partial_name_copy, partial_file_name, partial_name_len); 149558ce124SJim Ingham partial_name_copy[partial_name_len] = '\0'; 150558ce124SJim Ingham 151710dd5aeSGreg Clayton // We'll need to save a copy of the remainder for comparison, which we do here. 152558ce124SJim Ingham char remainder[PATH_MAX]; 153558ce124SJim Ingham 154558ce124SJim Ingham // end_ptr will point past the last / in partial_name_copy, or if there is no slash to the beginning of the string. 155558ce124SJim Ingham char *end_ptr; 156558ce124SJim Ingham 157558ce124SJim Ingham end_ptr = strrchr(partial_name_copy, '/'); 158558ce124SJim Ingham 159558ce124SJim Ingham // This will store the resolved form of the containing directory 160558ce124SJim Ingham char containing_part[PATH_MAX]; 161558ce124SJim Ingham 162558ce124SJim Ingham if (end_ptr == NULL) 163558ce124SJim Ingham { 164558ce124SJim Ingham // There's no directory. If the thing begins with a "~" then this is a bare 165558ce124SJim Ingham // user name. 166558ce124SJim Ingham if (*partial_name_copy == '~') 167558ce124SJim Ingham { 168558ce124SJim Ingham // Nothing here but the user name. We could just put a slash on the end, 1697cc478b9SJim Ingham // but for completeness sake we'll resolve the user name and only put a slash 170558ce124SJim Ingham // on the end if it exists. 1717cc478b9SJim Ingham char resolved_username[PATH_MAX]; 172c982c768SGreg Clayton size_t resolved_username_len = FileSpec::ResolveUsername (partial_name_copy, resolved_username, 1737cc478b9SJim Ingham sizeof (resolved_username)); 1747cc478b9SJim Ingham 1757cc478b9SJim Ingham // Not sure how this would happen, a username longer than PATH_MAX? Still... 1767cc478b9SJim Ingham if (resolved_username_len >= sizeof (resolved_username)) 177558ce124SJim Ingham return matches.GetSize(); 17884363078SJim Ingham else if (resolved_username_len == 0) 1797cc478b9SJim Ingham { 1807cc478b9SJim Ingham // The user name didn't resolve, let's look in the password database for matches. 1817cc478b9SJim Ingham // The user name database contains duplicates, and is not in alphabetical order, so 1827cc478b9SJim Ingham // we'll use a set to manage that for us. 18384363078SJim Ingham FileSpec::ResolvePartialUsername (partial_name_copy, matches); 18484363078SJim Ingham if (matches.GetSize() > 0) 1857cc478b9SJim Ingham saw_directory = true; 1867cc478b9SJim Ingham return matches.GetSize(); 1877cc478b9SJim Ingham } 18884363078SJim Ingham else 18984363078SJim Ingham { 190558ce124SJim Ingham //The thing exists, put a '/' on the end, and return it... 191558ce124SJim Ingham // FIXME: complete user names here: 192558ce124SJim Ingham partial_name_copy[partial_name_len] = '/'; 193558ce124SJim Ingham partial_name_copy[partial_name_len+1] = '\0'; 194558ce124SJim Ingham matches.AppendString(partial_name_copy); 195021b605dSBenjamin Kramer saw_directory = true; 196558ce124SJim Ingham return matches.GetSize(); 197558ce124SJim Ingham } 19884363078SJim Ingham } 199558ce124SJim Ingham else 200558ce124SJim Ingham { 201558ce124SJim Ingham // The containing part is the CWD, and the whole string is the remainder. 202558ce124SJim Ingham containing_part[0] = '.'; 203558ce124SJim Ingham containing_part[1] = '\0'; 204558ce124SJim Ingham strcpy(remainder, partial_name_copy); 205558ce124SJim Ingham end_ptr = partial_name_copy; 206558ce124SJim Ingham } 207558ce124SJim Ingham } 208558ce124SJim Ingham else 209558ce124SJim Ingham { 210558ce124SJim Ingham if (end_ptr == partial_name_copy) 211558ce124SJim Ingham { 212558ce124SJim Ingham // We're completing a file or directory in the root volume. 213558ce124SJim Ingham containing_part[0] = '/'; 214558ce124SJim Ingham containing_part[1] = '\0'; 215558ce124SJim Ingham } 216558ce124SJim Ingham else 217558ce124SJim Ingham { 218558ce124SJim Ingham size_t len = end_ptr - partial_name_copy; 219558ce124SJim Ingham memcpy(containing_part, partial_name_copy, len); 220558ce124SJim Ingham containing_part[len] = '\0'; 221558ce124SJim Ingham } 222558ce124SJim Ingham // Push end_ptr past the final "/" and set remainder. 223558ce124SJim Ingham end_ptr++; 224558ce124SJim Ingham strcpy(remainder, end_ptr); 225558ce124SJim Ingham } 226558ce124SJim Ingham 2277cc478b9SJim Ingham // Look for a user name in the containing part, and if it's there, resolve it and stick the 228558ce124SJim Ingham // result back into the containing_part: 229558ce124SJim Ingham 230558ce124SJim Ingham if (*partial_name_copy == '~') 231558ce124SJim Ingham { 23284363078SJim Ingham size_t resolved_username_len = FileSpec::ResolveUsername(containing_part, 23384363078SJim Ingham containing_part, 23484363078SJim Ingham sizeof (containing_part)); 235558ce124SJim Ingham // User name doesn't exist, we're not getting any further... 236a0807356SGreg Clayton if (resolved_username_len == 0 || resolved_username_len >= sizeof (containing_part)) 237558ce124SJim Ingham return matches.GetSize(); 238558ce124SJim Ingham } 239558ce124SJim Ingham 240558ce124SJim Ingham // Okay, containing_part is now the directory we want to open and look for files: 241558ce124SJim Ingham 2429b62fd2fSGreg Clayton lldb_utility::CleanUp <DIR *, int> dir_stream (opendir(containing_part), NULL, closedir); 2439b62fd2fSGreg Clayton if (!dir_stream.is_valid()) 244558ce124SJim Ingham return matches.GetSize(); 245558ce124SJim Ingham 246558ce124SJim Ingham struct dirent *dirent_buf; 247558ce124SJim Ingham 248558ce124SJim Ingham size_t baselen = end_ptr - partial_name_copy; 249558ce124SJim Ingham 2509b62fd2fSGreg Clayton while ((dirent_buf = readdir(dir_stream.get())) != NULL) 251558ce124SJim Ingham { 252558ce124SJim Ingham char *name = dirent_buf->d_name; 253558ce124SJim Ingham 254558ce124SJim Ingham // Omit ".", ".." and any . files if the match string doesn't start with . 255558ce124SJim Ingham if (name[0] == '.') 256558ce124SJim Ingham { 257558ce124SJim Ingham if (name[1] == '\0') 258558ce124SJim Ingham continue; 259558ce124SJim Ingham else if (name[1] == '.' && name[2] == '\0') 260558ce124SJim Ingham continue; 261558ce124SJim Ingham else if (remainder[0] != '.') 262558ce124SJim Ingham continue; 263558ce124SJim Ingham } 264558ce124SJim Ingham 2657cc478b9SJim Ingham // If we found a directory, we put a "/" at the end of the name. 2667cc478b9SJim Ingham 267558ce124SJim Ingham if (remainder[0] == '\0' || strstr(dirent_buf->d_name, remainder) == name) 268558ce124SJim Ingham { 269558ce124SJim Ingham if (strlen(name) + baselen >= PATH_MAX) 270558ce124SJim Ingham continue; 271558ce124SJim Ingham 272558ce124SJim Ingham strcpy(end_ptr, name); 273558ce124SJim Ingham 274558ce124SJim Ingham bool isa_directory = false; 275558ce124SJim Ingham if (dirent_buf->d_type & DT_DIR) 276558ce124SJim Ingham isa_directory = true; 277558ce124SJim Ingham else if (dirent_buf->d_type & DT_LNK) 278558ce124SJim Ingham { 279558ce124SJim Ingham struct stat stat_buf; 280d9761cd4SJason Molenda if ((stat(partial_name_copy, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) 281558ce124SJim Ingham isa_directory = true; 282558ce124SJim Ingham } 283558ce124SJim Ingham 284558ce124SJim Ingham if (isa_directory) 285558ce124SJim Ingham { 286558ce124SJim Ingham saw_directory = true; 287558ce124SJim Ingham size_t len = strlen(partial_name_copy); 288558ce124SJim Ingham partial_name_copy[len] = '/'; 289558ce124SJim Ingham partial_name_copy[len + 1] = '\0'; 290558ce124SJim Ingham } 291558ce124SJim Ingham if (only_directories && !isa_directory) 292558ce124SJim Ingham continue; 293558ce124SJim Ingham matches.AppendString(partial_name_copy); 294558ce124SJim Ingham } 295558ce124SJim Ingham } 296558ce124SJim Ingham 297558ce124SJim Ingham return matches.GetSize(); 298558ce124SJim Ingham } 299558ce124SJim Ingham 300558ce124SJim Ingham int 301558ce124SJim Ingham CommandCompletions::DiskFiles 302558ce124SJim Ingham ( 303558ce124SJim Ingham CommandInterpreter &interpreter, 304558ce124SJim Ingham const char *partial_file_name, 305558ce124SJim Ingham int match_start_point, 306558ce124SJim Ingham int max_return_elements, 307558ce124SJim Ingham SearchFilter *searcher, 308558ce124SJim Ingham bool &word_complete, 309558ce124SJim Ingham StringList &matches 310558ce124SJim Ingham ) 311558ce124SJim Ingham { 312558ce124SJim Ingham 313558ce124SJim Ingham int ret_val = DiskFilesOrDirectories (partial_file_name, 314558ce124SJim Ingham false, 315558ce124SJim Ingham word_complete, 316558ce124SJim Ingham matches); 317558ce124SJim Ingham word_complete = !word_complete; 318558ce124SJim Ingham return ret_val; 319558ce124SJim Ingham } 320558ce124SJim Ingham 321558ce124SJim Ingham int 322558ce124SJim Ingham CommandCompletions::DiskDirectories 323558ce124SJim Ingham ( 324558ce124SJim Ingham CommandInterpreter &interpreter, 325558ce124SJim Ingham const char *partial_file_name, 326558ce124SJim Ingham int match_start_point, 327558ce124SJim Ingham int max_return_elements, 328558ce124SJim Ingham SearchFilter *searcher, 329558ce124SJim Ingham bool &word_complete, 330558ce124SJim Ingham StringList &matches 331558ce124SJim Ingham ) 332558ce124SJim Ingham { 333558ce124SJim Ingham int ret_val = DiskFilesOrDirectories (partial_file_name, 334558ce124SJim Ingham true, 335558ce124SJim Ingham word_complete, 336558ce124SJim Ingham matches); 337558ce124SJim Ingham word_complete = false; 338558ce124SJim Ingham return ret_val; 339558ce124SJim Ingham } 340558ce124SJim Ingham 341c9af18a5SGreg Clayton int 3426611103cSGreg Clayton CommandCompletions::Modules 3436611103cSGreg Clayton ( 3446611103cSGreg Clayton CommandInterpreter &interpreter, 3456611103cSGreg Clayton const char *partial_file_name, 346c9af18a5SGreg Clayton int match_start_point, 347c9af18a5SGreg Clayton int max_return_elements, 348c9af18a5SGreg Clayton SearchFilter *searcher, 349558ce124SJim Ingham bool &word_complete, 3506611103cSGreg Clayton StringList &matches 3516611103cSGreg Clayton ) 352c9af18a5SGreg Clayton { 353558ce124SJim Ingham word_complete = true; 3546611103cSGreg Clayton ModuleCompleter completer (interpreter, 3556611103cSGreg Clayton partial_file_name, 3566611103cSGreg Clayton match_start_point, 3576611103cSGreg Clayton max_return_elements, 3586611103cSGreg Clayton matches); 359c9af18a5SGreg Clayton 360c9af18a5SGreg Clayton if (searcher == NULL) 361c9af18a5SGreg Clayton { 3622976d00aSJim Ingham lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); 363c9af18a5SGreg Clayton SearchFilter null_searcher (target_sp); 364c9af18a5SGreg Clayton completer.DoCompletion (&null_searcher); 365c9af18a5SGreg Clayton } 366c9af18a5SGreg Clayton else 367c9af18a5SGreg Clayton { 368c9af18a5SGreg Clayton completer.DoCompletion (searcher); 369c9af18a5SGreg Clayton } 370c9af18a5SGreg Clayton return matches.GetSize(); 371c9af18a5SGreg Clayton } 372c9af18a5SGreg Clayton 373c9af18a5SGreg Clayton int 3746611103cSGreg Clayton CommandCompletions::Symbols 3756611103cSGreg Clayton ( 3766611103cSGreg Clayton CommandInterpreter &interpreter, 3776611103cSGreg Clayton const char *partial_file_name, 378c9af18a5SGreg Clayton int match_start_point, 379c9af18a5SGreg Clayton int max_return_elements, 380c9af18a5SGreg Clayton SearchFilter *searcher, 381558ce124SJim Ingham bool &word_complete, 3826611103cSGreg Clayton StringList &matches) 383c9af18a5SGreg Clayton { 384558ce124SJim Ingham word_complete = true; 3856611103cSGreg Clayton SymbolCompleter completer (interpreter, 3866611103cSGreg Clayton partial_file_name, 3876611103cSGreg Clayton match_start_point, 3886611103cSGreg Clayton max_return_elements, 3896611103cSGreg Clayton matches); 390c9af18a5SGreg Clayton 391c9af18a5SGreg Clayton if (searcher == NULL) 392c9af18a5SGreg Clayton { 3932976d00aSJim Ingham lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); 394c9af18a5SGreg Clayton SearchFilter null_searcher (target_sp); 395c9af18a5SGreg Clayton completer.DoCompletion (&null_searcher); 396c9af18a5SGreg Clayton } 397c9af18a5SGreg Clayton else 398c9af18a5SGreg Clayton { 399c9af18a5SGreg Clayton completer.DoCompletion (searcher); 400c9af18a5SGreg Clayton } 401c9af18a5SGreg Clayton return matches.GetSize(); 402c9af18a5SGreg Clayton } 403c9af18a5SGreg Clayton 4043df9a8dfSCaroline Tice int 4053df9a8dfSCaroline Tice CommandCompletions::SettingsNames (CommandInterpreter &interpreter, 4063df9a8dfSCaroline Tice const char *partial_setting_name, 4073df9a8dfSCaroline Tice int match_start_point, 4083df9a8dfSCaroline Tice int max_return_elements, 4093df9a8dfSCaroline Tice SearchFilter *searcher, 4103df9a8dfSCaroline Tice bool &word_complete, 4113df9a8dfSCaroline Tice StringList &matches) 4123df9a8dfSCaroline Tice { 41367cc0636SGreg Clayton // Cache the full setting name list 41467cc0636SGreg Clayton static StringList g_property_names; 41567cc0636SGreg Clayton if (g_property_names.GetSize() == 0) 41667cc0636SGreg Clayton { 41767cc0636SGreg Clayton // Generate the full setting name list on demand 41867cc0636SGreg Clayton lldb::OptionValuePropertiesSP properties_sp (interpreter.GetDebugger().GetValueProperties()); 41967cc0636SGreg Clayton if (properties_sp) 42067cc0636SGreg Clayton { 42167cc0636SGreg Clayton StreamString strm; 42267cc0636SGreg Clayton properties_sp->DumpValue(NULL, strm, OptionValue::eDumpOptionName); 42367cc0636SGreg Clayton const std::string &str = strm.GetString(); 42467cc0636SGreg Clayton g_property_names.SplitIntoLines(str.c_str(), str.size()); 42567cc0636SGreg Clayton } 42667cc0636SGreg Clayton } 4273df9a8dfSCaroline Tice 42867cc0636SGreg Clayton size_t exact_matches_idx = SIZE_MAX; 42967cc0636SGreg Clayton const size_t num_matches = g_property_names.AutoComplete (partial_setting_name, matches, exact_matches_idx); 43067cc0636SGreg Clayton word_complete = exact_matches_idx != SIZE_MAX; 43167cc0636SGreg Clayton return num_matches; 4323df9a8dfSCaroline Tice } 4333df9a8dfSCaroline Tice 434ab65b34fSGreg Clayton 435ab65b34fSGreg Clayton int 436ab65b34fSGreg Clayton CommandCompletions::PlatformPluginNames (CommandInterpreter &interpreter, 437ab65b34fSGreg Clayton const char *partial_name, 438ab65b34fSGreg Clayton int match_start_point, 439ab65b34fSGreg Clayton int max_return_elements, 440ab65b34fSGreg Clayton SearchFilter *searcher, 441ab65b34fSGreg Clayton bool &word_complete, 442ab65b34fSGreg Clayton lldb_private::StringList &matches) 443ab65b34fSGreg Clayton { 444ab65b34fSGreg Clayton const uint32_t num_matches = PluginManager::AutoCompletePlatformName(partial_name, matches); 445ab65b34fSGreg Clayton word_complete = num_matches == 1; 446ab65b34fSGreg Clayton return num_matches; 447ab65b34fSGreg Clayton } 448ab65b34fSGreg Clayton 449ab65b34fSGreg Clayton int 450ab65b34fSGreg Clayton CommandCompletions::ArchitectureNames (CommandInterpreter &interpreter, 451ab65b34fSGreg Clayton const char *partial_name, 452ab65b34fSGreg Clayton int match_start_point, 453ab65b34fSGreg Clayton int max_return_elements, 454ab65b34fSGreg Clayton SearchFilter *searcher, 455ab65b34fSGreg Clayton bool &word_complete, 456ab65b34fSGreg Clayton lldb_private::StringList &matches) 457ab65b34fSGreg Clayton { 458ab65b34fSGreg Clayton const uint32_t num_matches = ArchSpec::AutoComplete (partial_name, matches); 459ab65b34fSGreg Clayton word_complete = num_matches == 1; 460ab65b34fSGreg Clayton return num_matches; 461ab65b34fSGreg Clayton } 462ab65b34fSGreg Clayton 463ab65b34fSGreg Clayton 464*f21feadcSGreg Clayton int 465*f21feadcSGreg Clayton CommandCompletions::VariablePath (CommandInterpreter &interpreter, 466*f21feadcSGreg Clayton const char *partial_name, 467*f21feadcSGreg Clayton int match_start_point, 468*f21feadcSGreg Clayton int max_return_elements, 469*f21feadcSGreg Clayton SearchFilter *searcher, 470*f21feadcSGreg Clayton bool &word_complete, 471*f21feadcSGreg Clayton lldb_private::StringList &matches) 472*f21feadcSGreg Clayton { 473*f21feadcSGreg Clayton return Variable::AutoComplete (interpreter.GetExecutionContext(), partial_name, matches, word_complete); 474*f21feadcSGreg Clayton } 475*f21feadcSGreg Clayton 476*f21feadcSGreg Clayton 4776611103cSGreg Clayton CommandCompletions::Completer::Completer 4786611103cSGreg Clayton ( 4796611103cSGreg Clayton CommandInterpreter &interpreter, 480c9af18a5SGreg Clayton const char *completion_str, 481c9af18a5SGreg Clayton int match_start_point, 482c9af18a5SGreg Clayton int max_return_elements, 483c9af18a5SGreg Clayton StringList &matches 484c9af18a5SGreg Clayton ) : 4856611103cSGreg Clayton m_interpreter (interpreter), 486c9af18a5SGreg Clayton m_completion_str (completion_str), 487c9af18a5SGreg Clayton m_match_start_point (match_start_point), 488c9af18a5SGreg Clayton m_max_return_elements (max_return_elements), 489c9af18a5SGreg Clayton m_matches (matches) 490c9af18a5SGreg Clayton { 491c9af18a5SGreg Clayton } 492c9af18a5SGreg Clayton 493c9af18a5SGreg Clayton CommandCompletions::Completer::~Completer () 494c9af18a5SGreg Clayton { 495c9af18a5SGreg Clayton 496c9af18a5SGreg Clayton } 497c9af18a5SGreg Clayton 498c9af18a5SGreg Clayton //---------------------------------------------------------------------- 499c9af18a5SGreg Clayton // SourceFileCompleter 500c9af18a5SGreg Clayton //---------------------------------------------------------------------- 501c9af18a5SGreg Clayton 5026611103cSGreg Clayton CommandCompletions::SourceFileCompleter::SourceFileCompleter 5036611103cSGreg Clayton ( 5046611103cSGreg Clayton CommandInterpreter &interpreter, 505c9af18a5SGreg Clayton bool include_support_files, 506c9af18a5SGreg Clayton const char *completion_str, 507c9af18a5SGreg Clayton int match_start_point, 508c9af18a5SGreg Clayton int max_return_elements, 509c9af18a5SGreg Clayton StringList &matches 510c9af18a5SGreg Clayton ) : 5116611103cSGreg Clayton CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches), 512c9af18a5SGreg Clayton m_include_support_files (include_support_files), 513c9af18a5SGreg Clayton m_matching_files() 514c9af18a5SGreg Clayton { 515274060b6SGreg Clayton FileSpec partial_spec (m_completion_str.c_str(), false); 516c9af18a5SGreg Clayton m_file_name = partial_spec.GetFilename().GetCString(); 517c9af18a5SGreg Clayton m_dir_name = partial_spec.GetDirectory().GetCString(); 518c9af18a5SGreg Clayton } 519c9af18a5SGreg Clayton 520c9af18a5SGreg Clayton Searcher::Depth 521c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::GetDepth() 522c9af18a5SGreg Clayton { 523c9af18a5SGreg Clayton return eDepthCompUnit; 524c9af18a5SGreg Clayton } 525c9af18a5SGreg Clayton 526c9af18a5SGreg Clayton Searcher::CallbackReturn 527c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::SearchCallback ( 528c9af18a5SGreg Clayton SearchFilter &filter, 529c9af18a5SGreg Clayton SymbolContext &context, 530c9af18a5SGreg Clayton Address *addr, 531c9af18a5SGreg Clayton bool complete 532c9af18a5SGreg Clayton ) 533c9af18a5SGreg Clayton { 534c9af18a5SGreg Clayton if (context.comp_unit != NULL) 535c9af18a5SGreg Clayton { 536c9af18a5SGreg Clayton if (m_include_support_files) 537c9af18a5SGreg Clayton { 538c9af18a5SGreg Clayton FileSpecList supporting_files = context.comp_unit->GetSupportFiles(); 539c9af18a5SGreg Clayton for (size_t sfiles = 0; sfiles < supporting_files.GetSize(); sfiles++) 540c9af18a5SGreg Clayton { 541c9af18a5SGreg Clayton const FileSpec &sfile_spec = supporting_files.GetFileSpecAtIndex(sfiles); 542c9af18a5SGreg Clayton const char *sfile_file_name = sfile_spec.GetFilename().GetCString(); 543c9af18a5SGreg Clayton const char *sfile_dir_name = sfile_spec.GetFilename().GetCString(); 544c9af18a5SGreg Clayton bool match = false; 545c9af18a5SGreg Clayton if (m_file_name && sfile_file_name 546c9af18a5SGreg Clayton && strstr (sfile_file_name, m_file_name) == sfile_file_name) 547c9af18a5SGreg Clayton match = true; 548c9af18a5SGreg Clayton if (match && m_dir_name && sfile_dir_name 549c9af18a5SGreg Clayton && strstr (sfile_dir_name, m_dir_name) != sfile_dir_name) 550c9af18a5SGreg Clayton match = false; 551c9af18a5SGreg Clayton 552c9af18a5SGreg Clayton if (match) 553c9af18a5SGreg Clayton { 554c9af18a5SGreg Clayton m_matching_files.AppendIfUnique(sfile_spec); 555c9af18a5SGreg Clayton } 556c9af18a5SGreg Clayton } 557c9af18a5SGreg Clayton 558c9af18a5SGreg Clayton } 559c9af18a5SGreg Clayton else 560c9af18a5SGreg Clayton { 561c9af18a5SGreg Clayton const char *cur_file_name = context.comp_unit->GetFilename().GetCString(); 562c9af18a5SGreg Clayton const char *cur_dir_name = context.comp_unit->GetDirectory().GetCString(); 563c9af18a5SGreg Clayton 564c9af18a5SGreg Clayton bool match = false; 565c9af18a5SGreg Clayton if (m_file_name && cur_file_name 566c9af18a5SGreg Clayton && strstr (cur_file_name, m_file_name) == cur_file_name) 567c9af18a5SGreg Clayton match = true; 568c9af18a5SGreg Clayton 569c9af18a5SGreg Clayton if (match && m_dir_name && cur_dir_name 570c9af18a5SGreg Clayton && strstr (cur_dir_name, m_dir_name) != cur_dir_name) 571c9af18a5SGreg Clayton match = false; 572c9af18a5SGreg Clayton 573c9af18a5SGreg Clayton if (match) 574c9af18a5SGreg Clayton { 575c9af18a5SGreg Clayton m_matching_files.AppendIfUnique(context.comp_unit); 576c9af18a5SGreg Clayton } 577c9af18a5SGreg Clayton } 578c9af18a5SGreg Clayton } 579c9af18a5SGreg Clayton return Searcher::eCallbackReturnContinue; 580c9af18a5SGreg Clayton } 581c9af18a5SGreg Clayton 582c9af18a5SGreg Clayton size_t 583c9af18a5SGreg Clayton CommandCompletions::SourceFileCompleter::DoCompletion (SearchFilter *filter) 584c9af18a5SGreg Clayton { 585c9af18a5SGreg Clayton filter->Search (*this); 586c9af18a5SGreg Clayton // Now convert the filelist to completions: 587c9af18a5SGreg Clayton for (size_t i = 0; i < m_matching_files.GetSize(); i++) 588c9af18a5SGreg Clayton { 589c9af18a5SGreg Clayton m_matches.AppendString (m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); 590c9af18a5SGreg Clayton } 591c9af18a5SGreg Clayton return m_matches.GetSize(); 592c9af18a5SGreg Clayton 593c9af18a5SGreg Clayton } 594c9af18a5SGreg Clayton 595c9af18a5SGreg Clayton //---------------------------------------------------------------------- 596c9af18a5SGreg Clayton // SymbolCompleter 597c9af18a5SGreg Clayton //---------------------------------------------------------------------- 598c9af18a5SGreg Clayton 599c9af18a5SGreg Clayton static bool 600c9af18a5SGreg Clayton regex_chars (const char comp) 601c9af18a5SGreg Clayton { 602c9af18a5SGreg Clayton if (comp == '[' || comp == ']' || comp == '(' || comp == ')') 603c9af18a5SGreg Clayton return true; 604c9af18a5SGreg Clayton else 605c9af18a5SGreg Clayton return false; 606c9af18a5SGreg Clayton } 6076611103cSGreg Clayton CommandCompletions::SymbolCompleter::SymbolCompleter 6086611103cSGreg Clayton ( 6096611103cSGreg Clayton CommandInterpreter &interpreter, 610c9af18a5SGreg Clayton const char *completion_str, 611c9af18a5SGreg Clayton int match_start_point, 612c9af18a5SGreg Clayton int max_return_elements, 613c9af18a5SGreg Clayton StringList &matches 614c9af18a5SGreg Clayton ) : 6156611103cSGreg Clayton CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches) 616c9af18a5SGreg Clayton { 617c9af18a5SGreg Clayton std::string regex_str ("^"); 618c9af18a5SGreg Clayton regex_str.append(completion_str); 619c9af18a5SGreg Clayton regex_str.append(".*"); 620c9af18a5SGreg Clayton std::string::iterator pos; 621c9af18a5SGreg Clayton 622c9af18a5SGreg Clayton pos = find_if(regex_str.begin(), regex_str.end(), regex_chars); 623c9af18a5SGreg Clayton while (pos < regex_str.end()) { 624c9af18a5SGreg Clayton pos = regex_str.insert(pos, '\\'); 625c9af18a5SGreg Clayton pos += 2; 626c9af18a5SGreg Clayton pos = find_if(pos, regex_str.end(), regex_chars); 627c9af18a5SGreg Clayton } 628c9af18a5SGreg Clayton m_regex.Compile(regex_str.c_str()); 629c9af18a5SGreg Clayton } 630c9af18a5SGreg Clayton 631c9af18a5SGreg Clayton Searcher::Depth 632c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::GetDepth() 633c9af18a5SGreg Clayton { 634c9af18a5SGreg Clayton return eDepthModule; 635c9af18a5SGreg Clayton } 636c9af18a5SGreg Clayton 637c9af18a5SGreg Clayton Searcher::CallbackReturn 638c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::SearchCallback ( 639c9af18a5SGreg Clayton SearchFilter &filter, 640c9af18a5SGreg Clayton SymbolContext &context, 641c9af18a5SGreg Clayton Address *addr, 642c9af18a5SGreg Clayton bool complete 643c9af18a5SGreg Clayton ) 644c9af18a5SGreg Clayton { 645c9af18a5SGreg Clayton if (context.module_sp) 646c9af18a5SGreg Clayton { 647931180e6SGreg Clayton SymbolContextList sc_list; 648931180e6SGreg Clayton const bool include_symbols = true; 6499df05fbbSSean Callanan const bool include_inlines = true; 650931180e6SGreg Clayton const bool append = true; 6519df05fbbSSean Callanan context.module_sp->FindFunctions (m_regex, include_symbols, include_inlines, append, sc_list); 652c9af18a5SGreg Clayton 653c9af18a5SGreg Clayton SymbolContext sc; 654c9af18a5SGreg Clayton // Now add the functions & symbols to the list - only add if unique: 655931180e6SGreg Clayton for (uint32_t i = 0; i < sc_list.GetSize(); i++) 656c9af18a5SGreg Clayton { 657931180e6SGreg Clayton if (sc_list.GetContextAtIndex(i, sc)) 658c9af18a5SGreg Clayton { 659530a413cSJim Ingham ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled); 660530a413cSJim Ingham if (!func_name.IsEmpty()) 661530a413cSJim Ingham m_match_set.insert (func_name); 662c9af18a5SGreg Clayton } 663c9af18a5SGreg Clayton } 664c9af18a5SGreg Clayton } 665c9af18a5SGreg Clayton return Searcher::eCallbackReturnContinue; 666c9af18a5SGreg Clayton } 667c9af18a5SGreg Clayton 668c9af18a5SGreg Clayton size_t 669c9af18a5SGreg Clayton CommandCompletions::SymbolCompleter::DoCompletion (SearchFilter *filter) 670c9af18a5SGreg Clayton { 671c9af18a5SGreg Clayton filter->Search (*this); 672c9af18a5SGreg Clayton collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); 673c9af18a5SGreg Clayton for (pos = m_match_set.begin(); pos != end; pos++) 674c9af18a5SGreg Clayton m_matches.AppendString((*pos).GetCString()); 675c9af18a5SGreg Clayton 676c9af18a5SGreg Clayton return m_matches.GetSize(); 677c9af18a5SGreg Clayton } 678c9af18a5SGreg Clayton 679c9af18a5SGreg Clayton //---------------------------------------------------------------------- 680c9af18a5SGreg Clayton // ModuleCompleter 681c9af18a5SGreg Clayton //---------------------------------------------------------------------- 6826611103cSGreg Clayton CommandCompletions::ModuleCompleter::ModuleCompleter 6836611103cSGreg Clayton ( 6846611103cSGreg Clayton CommandInterpreter &interpreter, 685c9af18a5SGreg Clayton const char *completion_str, 686c9af18a5SGreg Clayton int match_start_point, 687c9af18a5SGreg Clayton int max_return_elements, 688c9af18a5SGreg Clayton StringList &matches 689c9af18a5SGreg Clayton ) : 6906611103cSGreg Clayton CommandCompletions::Completer (interpreter, completion_str, match_start_point, max_return_elements, matches) 691c9af18a5SGreg Clayton { 692274060b6SGreg Clayton FileSpec partial_spec (m_completion_str.c_str(), false); 693c9af18a5SGreg Clayton m_file_name = partial_spec.GetFilename().GetCString(); 694c9af18a5SGreg Clayton m_dir_name = partial_spec.GetDirectory().GetCString(); 695c9af18a5SGreg Clayton } 696c9af18a5SGreg Clayton 697c9af18a5SGreg Clayton Searcher::Depth 698c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::GetDepth() 699c9af18a5SGreg Clayton { 700c9af18a5SGreg Clayton return eDepthModule; 701c9af18a5SGreg Clayton } 702c9af18a5SGreg Clayton 703c9af18a5SGreg Clayton Searcher::CallbackReturn 704c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::SearchCallback ( 705c9af18a5SGreg Clayton SearchFilter &filter, 706c9af18a5SGreg Clayton SymbolContext &context, 707c9af18a5SGreg Clayton Address *addr, 708c9af18a5SGreg Clayton bool complete 709c9af18a5SGreg Clayton ) 710c9af18a5SGreg Clayton { 711747bcb03SGreg Clayton if (context.module_sp) 712c9af18a5SGreg Clayton { 713c9af18a5SGreg Clayton const char *cur_file_name = context.module_sp->GetFileSpec().GetFilename().GetCString(); 714c9af18a5SGreg Clayton const char *cur_dir_name = context.module_sp->GetFileSpec().GetDirectory().GetCString(); 715c9af18a5SGreg Clayton 716c9af18a5SGreg Clayton bool match = false; 717c9af18a5SGreg Clayton if (m_file_name && cur_file_name 718c9af18a5SGreg Clayton && strstr (cur_file_name, m_file_name) == cur_file_name) 719c9af18a5SGreg Clayton match = true; 720c9af18a5SGreg Clayton 721c9af18a5SGreg Clayton if (match && m_dir_name && cur_dir_name 722c9af18a5SGreg Clayton && strstr (cur_dir_name, m_dir_name) != cur_dir_name) 723c9af18a5SGreg Clayton match = false; 724c9af18a5SGreg Clayton 725c9af18a5SGreg Clayton if (match) 726c9af18a5SGreg Clayton { 727c9af18a5SGreg Clayton m_matches.AppendString (cur_file_name); 728c9af18a5SGreg Clayton } 729c9af18a5SGreg Clayton } 730c9af18a5SGreg Clayton return Searcher::eCallbackReturnContinue; 731c9af18a5SGreg Clayton } 732c9af18a5SGreg Clayton 733c9af18a5SGreg Clayton size_t 734c9af18a5SGreg Clayton CommandCompletions::ModuleCompleter::DoCompletion (SearchFilter *filter) 735c9af18a5SGreg Clayton { 736c9af18a5SGreg Clayton filter->Search (*this); 737c9af18a5SGreg Clayton return m_matches.GetSize(); 738c9af18a5SGreg Clayton } 739