From 7d9edf670b518e80af18a39366a316f1288280f5 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Wed, 15 Sep 2010 06:56:39 +0000 Subject: [PATCH] Modify "settings list" so you can specify a particular instance setting name, or a settings prefix, and it will list information about the subset of settings you requested. Also added tab-completion (now that it takes an optional argument). llvm-svn: 113952 --- .../lldb/Core/UserSettingsController.h | 8 + .../source/Commands/CommandObjectSettings.cpp | 52 ++++- lldb/source/Commands/CommandObjectSettings.h | 11 + lldb/source/Core/UserSettingsController.cpp | 203 ++++++++++++++++++ 4 files changed, 268 insertions(+), 6 deletions(-) diff --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h index a2455d0f4d34..c2d44116bbe5 100644 --- a/lldb/include/lldb/Core/UserSettingsController.h +++ b/lldb/include/lldb/Core/UserSettingsController.h @@ -138,6 +138,14 @@ public: StreamString &result_stream, Error &err); + static void + FindSettingsDescriptions (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + const char *search_name, + StreamString &result_stream, + Error &err); + static void GetAllVariableValues (CommandInterpreter &interpreter, lldb::UserSettingsControllerSP root, diff --git a/lldb/source/Commands/CommandObjectSettings.cpp b/lldb/source/Commands/CommandObjectSettings.cpp index b0db6373a07d..8e6a5b1184c1 100644 --- a/lldb/source/Commands/CommandObjectSettings.cpp +++ b/lldb/source/Commands/CommandObjectSettings.cpp @@ -367,8 +367,8 @@ CommandObjectSettingsShow::HandleArgumentCompletion (CommandInterpreter &interpr CommandObjectSettingsList::CommandObjectSettingsList () : CommandObject ("settings list", - "List all the internal debugger settings variables that are available to the user to 'set' or 'show'.", - "settings list") + "List and describe all the internal debugger settings variables that are available to the user to 'set' or 'show', or describe a particular variable or set of variables (by specifying the variable name or a common prefix).", + "settings list [ | ]") { } @@ -379,16 +379,31 @@ CommandObjectSettingsList::~CommandObjectSettingsList() bool CommandObjectSettingsList::Execute (CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result) + Args& command, + CommandReturnObject &result) { UserSettingsControllerSP root_settings = Debugger::GetSettingsController (); std::string current_prefix = root_settings->GetLevelName().AsCString(); Error err; - UserSettingsController::FindAllSettingsDescriptions (interpreter, root_settings, current_prefix, - result.GetOutputStream(), err); + if (command.GetArgumentCount() == 0) + { + UserSettingsController::FindAllSettingsDescriptions (interpreter, root_settings, current_prefix, + result.GetOutputStream(), err); + } + else if (command.GetArgumentCount() == 1) + { + const char *search_name = command.GetArgumentAtIndex (0); + UserSettingsController::FindSettingsDescriptions (interpreter, root_settings, current_prefix, + search_name, result.GetOutputStream(), err); + } + else + { + result.AppendError ("Too many aguments for 'settings list' command.\n"); + result.SetStatus (eReturnStatusFailed); + return false; + } if (err.Fail ()) { @@ -403,6 +418,31 @@ CommandObjectSettingsList::Execute (CommandInterpreter &interpreter, return result.Succeeded(); } +int +CommandObjectSettingsList::HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + std::string completion_str (input.GetArgumentAtIndex (cursor_index)); + completion_str.erase (cursor_char_position); + + CommandCompletions::InvokeCommonCompletionCallbacks (interpreter, + CommandCompletions::eSettingsNameCompletion, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + return matches.GetSize(); +} + //------------------------------------------------------------------------- // CommandObjectSettingsRemove //------------------------------------------------------------------------- diff --git a/lldb/source/Commands/CommandObjectSettings.h b/lldb/source/Commands/CommandObjectSettings.h index 0bfb3caff3c1..13b51442d0b3 100644 --- a/lldb/source/Commands/CommandObjectSettings.h +++ b/lldb/source/Commands/CommandObjectSettings.h @@ -149,6 +149,17 @@ public: Args& command, CommandReturnObject &result); + virtual int + HandleArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches); + private: }; diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp index 2acdbd05a2a1..b97aa1d7ea76 100644 --- a/lldb/source/Core/UserSettingsController.cpp +++ b/lldb/source/Core/UserSettingsController.cpp @@ -1109,6 +1109,209 @@ UserSettingsController::FindAllSettingsDescriptions (CommandInterpreter &interpr } } +void +UserSettingsController::FindSettingsDescriptions (CommandInterpreter &interpreter, + lldb::UserSettingsControllerSP root, + std::string ¤t_prefix, + const char *search_name, + StreamString &result_stream, + Error &err) +{ + Args names = UserSettingsController::BreakNameIntoPieces (search_name); + int num_pieces = names.GetArgumentCount (); + + if (num_pieces == 0) + return; + + if (root->GetLevelName().GetLength() > 0) + { + ConstString prefix (names.GetArgumentAtIndex (0)); + if (prefix != root->GetLevelName()) + { + std::string parent_prefix; + root->BuildParentPrefix (parent_prefix); + err.SetErrorStringWithFormat ("Cannot find match for '%s.%s'\n", parent_prefix.c_str(), + prefix.AsCString()); + return; + } + else + { + names.Shift(); + --num_pieces; + } + } + + // If there's nothing left then dump all global and instance descriptions for this root. + if (num_pieces == 0) + { + StreamString prefix_line; + StreamString description; + uint32_t max_len; + int num_entries = root->m_settings.global_settings.size(); + + max_len = FindMaxNameLength (root->m_settings.global_settings); + + result_stream.Printf ("\n'%s' variables:\n\n", search_name); + + if (num_entries > 0) + { + // Write out all "global" variables. + for (int i = 0; i < num_entries; ++i) + { + SettingEntry entry = root->m_settings.global_settings[i]; + description.Clear(); + if (entry.var_type == lldb::eSetVarTypeEnum) + { + StreamString enum_values_str; + UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); + description.Printf ("[static, enum] %s. Valid values: {%s} (default: '%s')", entry.description, + enum_values_str.GetData(), entry.enum_values[0].string_value); + } + else if (entry.default_value != NULL) + description.Printf ("[static, %s] %s (default: '%s')", GetTypeString (entry.var_type), + entry.description, entry.default_value); + else + description.Printf ("[static, %s] %s (default: '')", GetTypeString (entry.var_type), + entry.description); + interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), + max_len); + } + } + + num_entries = root->m_settings.instance_settings.size(); + max_len = FindMaxNameLength (root->m_settings.instance_settings); + + if (num_entries > 0) + { + // Write out all instance variables. + for (int i = 0; i < num_entries; ++i) + { + SettingEntry entry = root->m_settings.instance_settings[i]; + description.Clear(); + if (entry.var_type == lldb::eSetVarTypeEnum) + { + StreamString enum_values_str; + UserSettingsController::PrintEnumValues (entry.enum_values, enum_values_str); + description.Printf ("[instance, enum] %s. Valid values: {%s} (default: '%s')", entry.description, + enum_values_str.GetData(), entry.enum_values[0].string_value); + } + else if (entry.default_value != NULL) + description.Printf ("[instance, %s] %s (default: '%s')", GetTypeString (entry.var_type), + entry.description, entry.default_value); + else + description.Printf ("[instance, %s] %s (default: '')", GetTypeString (entry.var_type), + entry.description); + interpreter.OutputFormattedHelpText (result_stream, entry.var_name, "--", description.GetData(), + max_len); + } + } + } + else if (num_pieces == 1) + { + ConstString var_name (names.GetArgumentAtIndex (0)); + bool is_global = false; + + const SettingEntry *setting_entry = root->GetGlobalEntry (var_name); + + if (setting_entry == NULL) + setting_entry = root->GetInstanceEntry (var_name); + else + is_global = true; + + // Check to see if it is a global or instance variable name. + if (setting_entry != NULL) + { + StreamString description; + if (setting_entry->var_type == lldb::eSetVarTypeEnum) + { + StreamString enum_values_str; + UserSettingsController::PrintEnumValues (setting_entry->enum_values, enum_values_str); + description.Printf ("[%s, enum] %s. Valid values: {%s} (default: '%s')", + (is_global ? "static" : "instance"), + setting_entry->description, + enum_values_str.GetData(), setting_entry->enum_values[0].string_value); + } + else if (setting_entry->default_value != NULL) + description.Printf ("[%s, %s] %s (default: '%s')", + (is_global ? "static" : "instance"), + GetTypeString (setting_entry->var_type), + setting_entry->description, setting_entry->default_value); + else + description.Printf ("[%s, %s] %s (default: '')", + (is_global ? "static" : "instance"), + GetTypeString (setting_entry->var_type), + setting_entry->description); + interpreter.OutputFormattedHelpText (result_stream, setting_entry->var_name, "--", description.GetData(), + var_name.GetLength()); + } + else + { + // It must be a child name. + int num_children = root->GetNumChildren(); + bool found = false; + for (int i = 0; i < num_children && !found; ++i) + { + lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); + if (child) + { + ConstString child_prefix = child->GetLevelName(); + if (child_prefix == var_name) + { + found = true; + UserSettingsController::FindSettingsDescriptions (interpreter, child, current_prefix, + var_name.AsCString(), result_stream, err); + } + } + } + if (!found) + { + std::string parent_prefix; + root->BuildParentPrefix (parent_prefix); + err.SetErrorStringWithFormat ("Cannot find match for '%s.%s'\n", parent_prefix.c_str(), search_name); + return; + } + } + } + else + { + // It must be a child name; find the child and call this function recursively on child. + ConstString child_name (names.GetArgumentAtIndex (0)); + + StreamString rest_of_search_name; + for (int i = 0; i < num_pieces; ++i) + { + rest_of_search_name.Printf ("%s", names.GetArgumentAtIndex (i)); + if ((i + 1) < num_pieces) + rest_of_search_name.Printf ("."); + } + + int num_children = root->GetNumChildren(); + bool found = false; + for (int i = 0; i < num_children && !found; ++i) + { + lldb::UserSettingsControllerSP child = root->GetChildAtIndex (i); + if (child) + { + ConstString child_prefix = child->GetLevelName(); + if (child_prefix == child_name) + { + found = true; + UserSettingsController::FindSettingsDescriptions (interpreter, child, current_prefix, + rest_of_search_name.GetData(), result_stream, + err); + } + } + } + if (!found) + { + std::string parent_prefix; + root->BuildParentPrefix (parent_prefix); + err.SetErrorStringWithFormat ("Cannot find match for '%s.%s'\n", parent_prefix.c_str(), search_name); + return; + } + } +} + void UserSettingsController::GetAllVariableValues (CommandInterpreter &interpreter, lldb::UserSettingsControllerSP root,