15ffd83dbSDimitry Andric //===-- CommandObjectSettings.cpp -----------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "CommandObjectSettings.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "lldb/Host/OptionParser.h" 140b57cec5SDimitry Andric #include "lldb/Interpreter/CommandCompletions.h" 150b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h" 16fcaf7f86SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h" 170b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h" 180b57cec5SDimitry Andric #include "lldb/Interpreter/OptionValueProperties.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric using namespace lldb; 210b57cec5SDimitry Andric using namespace lldb_private; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric // CommandObjectSettingsSet 240b57cec5SDimitry Andric #define LLDB_OPTIONS_settings_set 250b57cec5SDimitry Andric #include "CommandOptions.inc" 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric class CommandObjectSettingsSet : public CommandObjectRaw { 280b57cec5SDimitry Andric public: 290b57cec5SDimitry Andric CommandObjectSettingsSet(CommandInterpreter &interpreter) 300b57cec5SDimitry Andric : CommandObjectRaw(interpreter, "settings set", 3104eeddc0SDimitry Andric "Set the value of the specified debugger setting.") { 320b57cec5SDimitry Andric CommandArgumentEntry arg1; 330b57cec5SDimitry Andric CommandArgumentEntry arg2; 340b57cec5SDimitry Andric CommandArgumentData var_name_arg; 350b57cec5SDimitry Andric CommandArgumentData value_arg; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 380b57cec5SDimitry Andric var_name_arg.arg_type = eArgTypeSettingVariableName; 390b57cec5SDimitry Andric var_name_arg.arg_repetition = eArgRepeatPlain; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 420b57cec5SDimitry Andric // argument entry. 430b57cec5SDimitry Andric arg1.push_back(var_name_arg); 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 460b57cec5SDimitry Andric value_arg.arg_type = eArgTypeValue; 470b57cec5SDimitry Andric value_arg.arg_repetition = eArgRepeatPlain; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 500b57cec5SDimitry Andric // argument entry. 510b57cec5SDimitry Andric arg2.push_back(value_arg); 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector. 540b57cec5SDimitry Andric m_arguments.push_back(arg1); 550b57cec5SDimitry Andric m_arguments.push_back(arg2); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric SetHelpLong( 580b57cec5SDimitry Andric "\nWhen setting a dictionary or array variable, you can set multiple entries \ 590b57cec5SDimitry Andric at once by giving the values to the set command. For example:" 600b57cec5SDimitry Andric R"( 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric (lldb) settings set target.run-args value1 value2 value3 630b57cec5SDimitry Andric (lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric (lldb) settings show target.run-args 660b57cec5SDimitry Andric [0]: 'value1' 670b57cec5SDimitry Andric [1]: 'value2' 680b57cec5SDimitry Andric [3]: 'value3' 690b57cec5SDimitry Andric (lldb) settings show target.env-vars 700b57cec5SDimitry Andric 'MYPATH=~/.:/usr/bin' 710b57cec5SDimitry Andric 'SOME_ENV_VAR=12345' 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric )" 740b57cec5SDimitry Andric "Warning: The 'set' command re-sets the entire array or dictionary. If you \ 750b57cec5SDimitry Andric just want to add, remove or update individual values (or add something to \ 760b57cec5SDimitry Andric the end), use one of the other settings sub-commands: append, replace, \ 770b57cec5SDimitry Andric insert-before or insert-after."); 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric ~CommandObjectSettingsSet() override = default; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric // Overrides base class's behavior where WantsCompletion = 830b57cec5SDimitry Andric // !WantsRawCommandString. 840b57cec5SDimitry Andric bool WantsCompletion() override { return true; } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric Options *GetOptions() override { return &m_options; } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric class CommandOptions : public Options { 890b57cec5SDimitry Andric public: 9081ad6265SDimitry Andric CommandOptions() = default; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric ~CommandOptions() override = default; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 950b57cec5SDimitry Andric ExecutionContext *execution_context) override { 960b57cec5SDimitry Andric Status error; 970b57cec5SDimitry Andric const int short_option = m_getopt_table[option_idx].val; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric switch (short_option) { 1000b57cec5SDimitry Andric case 'f': 1010b57cec5SDimitry Andric m_force = true; 1020b57cec5SDimitry Andric break; 1030b57cec5SDimitry Andric case 'g': 1040b57cec5SDimitry Andric m_global = true; 1050b57cec5SDimitry Andric break; 10681ad6265SDimitry Andric case 'e': 10781ad6265SDimitry Andric m_exists = true; 10881ad6265SDimitry Andric break; 1090b57cec5SDimitry Andric default: 1109dba64beSDimitry Andric llvm_unreachable("Unimplemented option"); 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric return error; 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override { 1170b57cec5SDimitry Andric m_global = false; 1180b57cec5SDimitry Andric m_force = false; 11981ad6265SDimitry Andric m_exists = false; 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 123bdd1243dSDimitry Andric return llvm::ArrayRef(g_settings_set_options); 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric // Instance variables to hold the values for command options. 127fe6060f1SDimitry Andric bool m_global = false; 12881ad6265SDimitry Andric bool m_force = false; 12981ad6265SDimitry Andric bool m_exists = false; 1300b57cec5SDimitry Andric }; 1310b57cec5SDimitry Andric 1329dba64beSDimitry Andric void 1339dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request, 1340b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override { 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric const size_t argc = request.GetParsedLine().GetArgumentCount(); 1370b57cec5SDimitry Andric const char *arg = nullptr; 1389dba64beSDimitry Andric size_t setting_var_idx; 1399dba64beSDimitry Andric for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) { 1400b57cec5SDimitry Andric arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); 1410b57cec5SDimitry Andric if (arg && arg[0] != '-') 1420b57cec5SDimitry Andric break; // We found our setting variable name index 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric if (request.GetCursorIndex() == setting_var_idx) { 1450b57cec5SDimitry Andric // Attempting to complete setting variable name 14606c3fb27SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 14706c3fb27SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, 14806c3fb27SDimitry Andric nullptr); 1499dba64beSDimitry Andric return; 1509dba64beSDimitry Andric } 151480093f4SDimitry Andric arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()); 1520b57cec5SDimitry Andric 1539dba64beSDimitry Andric if (!arg) 1549dba64beSDimitry Andric return; 1559dba64beSDimitry Andric 1560b57cec5SDimitry Andric // Complete option name 157bdd1243dSDimitry Andric if (arg[0] == '-') 1589dba64beSDimitry Andric return; 1599dba64beSDimitry Andric 1600b57cec5SDimitry Andric // Complete setting value 1610b57cec5SDimitry Andric const char *setting_var_name = 1620b57cec5SDimitry Andric request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); 1630b57cec5SDimitry Andric Status error; 16406c3fb27SDimitry Andric lldb::OptionValueSP value_sp( 16506c3fb27SDimitry Andric GetDebugger().GetPropertyValue(&m_exe_ctx, setting_var_name, error)); 1669dba64beSDimitry Andric if (!value_sp) 1679dba64beSDimitry Andric return; 1680b57cec5SDimitry Andric value_sp->AutoComplete(m_interpreter, request); 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric protected: 1725f757f3fSDimitry Andric void DoExecute(llvm::StringRef command, 1730b57cec5SDimitry Andric CommandReturnObject &result) override { 1740b57cec5SDimitry Andric Args cmd_args(command); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric // Process possible options. 1770b57cec5SDimitry Andric if (!ParseOptions(cmd_args, result)) 1785f757f3fSDimitry Andric return; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric const size_t min_argc = m_options.m_force ? 1 : 2; 1810b57cec5SDimitry Andric const size_t argc = cmd_args.GetArgumentCount(); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric if ((argc < min_argc) && (!m_options.m_global)) { 1840b57cec5SDimitry Andric result.AppendError("'settings set' takes more arguments"); 1855f757f3fSDimitry Andric return; 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric const char *var_name = cmd_args.GetArgumentAtIndex(0); 1890b57cec5SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) { 1900b57cec5SDimitry Andric result.AppendError( 1910b57cec5SDimitry Andric "'settings set' command requires a valid variable name"); 1925f757f3fSDimitry Andric return; 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric // A missing value corresponds to clearing the setting when "force" is 1960b57cec5SDimitry Andric // specified. 1970b57cec5SDimitry Andric if (argc == 1 && m_options.m_force) { 1980b57cec5SDimitry Andric Status error(GetDebugger().SetPropertyValue( 1990b57cec5SDimitry Andric &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef())); 2000b57cec5SDimitry Andric if (error.Fail()) { 2010b57cec5SDimitry Andric result.AppendError(error.AsCString()); 2020b57cec5SDimitry Andric } 2035f757f3fSDimitry Andric return; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric // Split the raw command into var_name and value pair. 2079dba64beSDimitry Andric llvm::StringRef var_value(command); 2089dba64beSDimitry Andric var_value = var_value.split(var_name).second.ltrim(); 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric Status error; 2119dba64beSDimitry Andric if (m_options.m_global) 2120b57cec5SDimitry Andric error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign, 2139dba64beSDimitry Andric var_name, var_value); 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric if (error.Success()) { 2160b57cec5SDimitry Andric // FIXME this is the same issue as the one in commands script import 2170b57cec5SDimitry Andric // we could be setting target.load-script-from-symbol-file which would 2180b57cec5SDimitry Andric // cause Python scripts to be loaded, which could run LLDB commands (e.g. 2190b57cec5SDimitry Andric // settings set target.process.python-os-plugin-path) and cause a crash 2200b57cec5SDimitry Andric // if we did not clear the command's exe_ctx first 2210b57cec5SDimitry Andric ExecutionContext exe_ctx(m_exe_ctx); 2220b57cec5SDimitry Andric m_exe_ctx.Clear(); 2230b57cec5SDimitry Andric error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign, 2249dba64beSDimitry Andric var_name, var_value); 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric 22781ad6265SDimitry Andric if (error.Fail() && !m_options.m_exists) { 2280b57cec5SDimitry Andric result.AppendError(error.AsCString()); 2295f757f3fSDimitry Andric return; 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 23281ad6265SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric private: 2360b57cec5SDimitry Andric CommandOptions m_options; 2370b57cec5SDimitry Andric }; 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric // CommandObjectSettingsShow -- Show current values 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric class CommandObjectSettingsShow : public CommandObjectParsed { 2420b57cec5SDimitry Andric public: 2430b57cec5SDimitry Andric CommandObjectSettingsShow(CommandInterpreter &interpreter) 2440b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "settings show", 2450b57cec5SDimitry Andric "Show matching debugger settings and their current " 2460b57cec5SDimitry Andric "values. Defaults to showing all settings.", 2470b57cec5SDimitry Andric nullptr) { 248*0fca6ea1SDimitry Andric AddSimpleArgumentList(eArgTypeSettingVariableName, eArgRepeatOptional); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric ~CommandObjectSettingsShow() override = default; 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric protected: 2545f757f3fSDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override { 2550b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult); 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric if (!args.empty()) { 2580b57cec5SDimitry Andric for (const auto &arg : args) { 2590b57cec5SDimitry Andric Status error(GetDebugger().DumpPropertyValue( 2609dba64beSDimitry Andric &m_exe_ctx, result.GetOutputStream(), arg.ref(), 2610b57cec5SDimitry Andric OptionValue::eDumpGroupValue)); 2620b57cec5SDimitry Andric if (error.Success()) { 2630b57cec5SDimitry Andric result.GetOutputStream().EOL(); 2640b57cec5SDimitry Andric } else { 2650b57cec5SDimitry Andric result.AppendError(error.AsCString()); 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric } else { 2690b57cec5SDimitry Andric GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(), 2700b57cec5SDimitry Andric OptionValue::eDumpGroupValue); 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric }; 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric // CommandObjectSettingsWrite -- Write settings to file 2760b57cec5SDimitry Andric #define LLDB_OPTIONS_settings_write 2770b57cec5SDimitry Andric #include "CommandOptions.inc" 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric class CommandObjectSettingsWrite : public CommandObjectParsed { 2800b57cec5SDimitry Andric public: 2810b57cec5SDimitry Andric CommandObjectSettingsWrite(CommandInterpreter &interpreter) 2820b57cec5SDimitry Andric : CommandObjectParsed( 2830b57cec5SDimitry Andric interpreter, "settings export", 2840b57cec5SDimitry Andric "Write matching debugger settings and their " 2850b57cec5SDimitry Andric "current values to a file that can be read in with " 2860b57cec5SDimitry Andric "\"settings read\". Defaults to writing all settings.", 28704eeddc0SDimitry Andric nullptr) { 288*0fca6ea1SDimitry Andric AddSimpleArgumentList(eArgTypeSettingVariableName, eArgRepeatOptional); 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric ~CommandObjectSettingsWrite() override = default; 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric Options *GetOptions() override { return &m_options; } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric class CommandOptions : public Options { 2960b57cec5SDimitry Andric public: 29781ad6265SDimitry Andric CommandOptions() = default; 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric ~CommandOptions() override = default; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 3020b57cec5SDimitry Andric ExecutionContext *execution_context) override { 3030b57cec5SDimitry Andric Status error; 3040b57cec5SDimitry Andric const int short_option = m_getopt_table[option_idx].val; 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric switch (short_option) { 3070b57cec5SDimitry Andric case 'f': 3085ffd83dbSDimitry Andric m_filename.assign(std::string(option_arg)); 3090b57cec5SDimitry Andric break; 3100b57cec5SDimitry Andric case 'a': 3110b57cec5SDimitry Andric m_append = true; 3120b57cec5SDimitry Andric break; 3130b57cec5SDimitry Andric default: 3149dba64beSDimitry Andric llvm_unreachable("Unimplemented option"); 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric return error; 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override { 3210b57cec5SDimitry Andric m_filename.clear(); 3220b57cec5SDimitry Andric m_append = false; 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 326bdd1243dSDimitry Andric return llvm::ArrayRef(g_settings_write_options); 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric // Instance variables to hold the values for command options. 3300b57cec5SDimitry Andric std::string m_filename; 3310b57cec5SDimitry Andric bool m_append = false; 3320b57cec5SDimitry Andric }; 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric protected: 3355f757f3fSDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override { 3360b57cec5SDimitry Andric FileSpec file_spec(m_options.m_filename); 3370b57cec5SDimitry Andric FileSystem::Instance().Resolve(file_spec); 3380b57cec5SDimitry Andric std::string path(file_spec.GetPath()); 339349cc55cSDimitry Andric auto options = File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate; 3400b57cec5SDimitry Andric if (m_options.m_append) 3419dba64beSDimitry Andric options |= File::eOpenOptionAppend; 3420b57cec5SDimitry Andric else 3439dba64beSDimitry Andric options |= File::eOpenOptionTruncate; 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric StreamFile out_file(path.c_str(), options, 3460b57cec5SDimitry Andric lldb::eFilePermissionsFileDefault); 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric if (!out_file.GetFile().IsValid()) { 3490b57cec5SDimitry Andric result.AppendErrorWithFormat("%s: unable to write to file", path.c_str()); 3505f757f3fSDimitry Andric return; 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric // Exporting should not be context sensitive. 3540b57cec5SDimitry Andric ExecutionContext clean_ctx; 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric if (args.empty()) { 3570b57cec5SDimitry Andric GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file, 3580b57cec5SDimitry Andric OptionValue::eDumpGroupExport); 3595f757f3fSDimitry Andric return; 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric for (const auto &arg : args) { 3630b57cec5SDimitry Andric Status error(GetDebugger().DumpPropertyValue( 3649dba64beSDimitry Andric &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport)); 3650b57cec5SDimitry Andric if (!error.Success()) { 3660b57cec5SDimitry Andric result.AppendError(error.AsCString()); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric private: 3720b57cec5SDimitry Andric CommandOptions m_options; 3730b57cec5SDimitry Andric }; 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric // CommandObjectSettingsRead -- Read settings from file 3760b57cec5SDimitry Andric #define LLDB_OPTIONS_settings_read 3770b57cec5SDimitry Andric #include "CommandOptions.inc" 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric class CommandObjectSettingsRead : public CommandObjectParsed { 3800b57cec5SDimitry Andric public: 3810b57cec5SDimitry Andric CommandObjectSettingsRead(CommandInterpreter &interpreter) 3820b57cec5SDimitry Andric : CommandObjectParsed( 3830b57cec5SDimitry Andric interpreter, "settings read", 3840b57cec5SDimitry Andric "Read settings previously saved to a file with \"settings write\".", 38504eeddc0SDimitry Andric nullptr) {} 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric ~CommandObjectSettingsRead() override = default; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric Options *GetOptions() override { return &m_options; } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric class CommandOptions : public Options { 3920b57cec5SDimitry Andric public: 39381ad6265SDimitry Andric CommandOptions() = default; 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric ~CommandOptions() override = default; 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 3980b57cec5SDimitry Andric ExecutionContext *execution_context) override { 3990b57cec5SDimitry Andric Status error; 4000b57cec5SDimitry Andric const int short_option = m_getopt_table[option_idx].val; 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric switch (short_option) { 4030b57cec5SDimitry Andric case 'f': 4045ffd83dbSDimitry Andric m_filename.assign(std::string(option_arg)); 4050b57cec5SDimitry Andric break; 4060b57cec5SDimitry Andric default: 4079dba64beSDimitry Andric llvm_unreachable("Unimplemented option"); 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric return error; 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override { 4140b57cec5SDimitry Andric m_filename.clear(); 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 418bdd1243dSDimitry Andric return llvm::ArrayRef(g_settings_read_options); 4190b57cec5SDimitry Andric } 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric // Instance variables to hold the values for command options. 4220b57cec5SDimitry Andric std::string m_filename; 4230b57cec5SDimitry Andric }; 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric protected: 4265f757f3fSDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override { 4270b57cec5SDimitry Andric FileSpec file(m_options.m_filename); 4280b57cec5SDimitry Andric FileSystem::Instance().Resolve(file); 4290b57cec5SDimitry Andric CommandInterpreterRunOptions options; 4300b57cec5SDimitry Andric options.SetAddToHistory(false); 4310b57cec5SDimitry Andric options.SetEchoCommands(false); 4320b57cec5SDimitry Andric options.SetPrintResults(true); 4330b57cec5SDimitry Andric options.SetPrintErrors(true); 4340b57cec5SDimitry Andric options.SetStopOnError(false); 435fe6060f1SDimitry Andric m_interpreter.HandleCommandsFromFile(file, options, result); 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric private: 4390b57cec5SDimitry Andric CommandOptions m_options; 4400b57cec5SDimitry Andric }; 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric // CommandObjectSettingsList -- List settable variables 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric class CommandObjectSettingsList : public CommandObjectParsed { 4450b57cec5SDimitry Andric public: 4460b57cec5SDimitry Andric CommandObjectSettingsList(CommandInterpreter &interpreter) 4470b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "settings list", 4480b57cec5SDimitry Andric "List and describe matching debugger settings. " 4490b57cec5SDimitry Andric "Defaults to all listing all settings.", 4500b57cec5SDimitry Andric nullptr) { 4510b57cec5SDimitry Andric CommandArgumentEntry arg; 4520b57cec5SDimitry Andric CommandArgumentData var_name_arg; 4530b57cec5SDimitry Andric CommandArgumentData prefix_name_arg; 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric // Define the first variant of this arg. 4560b57cec5SDimitry Andric var_name_arg.arg_type = eArgTypeSettingVariableName; 4570b57cec5SDimitry Andric var_name_arg.arg_repetition = eArgRepeatOptional; 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric // Define the second variant of this arg. 4600b57cec5SDimitry Andric prefix_name_arg.arg_type = eArgTypeSettingPrefix; 4610b57cec5SDimitry Andric prefix_name_arg.arg_repetition = eArgRepeatOptional; 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric arg.push_back(var_name_arg); 4640b57cec5SDimitry Andric arg.push_back(prefix_name_arg); 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector. 4670b57cec5SDimitry Andric m_arguments.push_back(arg); 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric ~CommandObjectSettingsList() override = default; 4710b57cec5SDimitry Andric 4729dba64beSDimitry Andric void 4739dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request, 4740b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override { 47506c3fb27SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 47606c3fb27SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, 47706c3fb27SDimitry Andric nullptr); 4780b57cec5SDimitry Andric } 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric protected: 4815f757f3fSDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override { 4820b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult); 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric const size_t argc = args.GetArgumentCount(); 4850b57cec5SDimitry Andric if (argc > 0) { 4860b57cec5SDimitry Andric const bool dump_qualified_name = true; 4870b57cec5SDimitry Andric 4885ffd83dbSDimitry Andric for (const Args::ArgEntry &arg : args) { 4895ffd83dbSDimitry Andric const char *property_path = arg.c_str(); 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric const Property *property = 4920b57cec5SDimitry Andric GetDebugger().GetValueProperties()->GetPropertyAtPath( 49306c3fb27SDimitry Andric &m_exe_ctx, property_path); 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric if (property) { 4960b57cec5SDimitry Andric property->DumpDescription(m_interpreter, result.GetOutputStream(), 0, 4970b57cec5SDimitry Andric dump_qualified_name); 4980b57cec5SDimitry Andric } else { 4990b57cec5SDimitry Andric result.AppendErrorWithFormat("invalid property path '%s'", 5000b57cec5SDimitry Andric property_path); 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric } else { 5040b57cec5SDimitry Andric GetDebugger().DumpAllDescriptions(m_interpreter, 5050b57cec5SDimitry Andric result.GetOutputStream()); 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric } 5080b57cec5SDimitry Andric }; 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric // CommandObjectSettingsRemove 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric class CommandObjectSettingsRemove : public CommandObjectRaw { 5130b57cec5SDimitry Andric public: 5140b57cec5SDimitry Andric CommandObjectSettingsRemove(CommandInterpreter &interpreter) 5150b57cec5SDimitry Andric : CommandObjectRaw(interpreter, "settings remove", 5160b57cec5SDimitry Andric "Remove a value from a setting, specified by array " 5170b57cec5SDimitry Andric "index or dictionary key.") { 5180b57cec5SDimitry Andric CommandArgumentEntry arg1; 5190b57cec5SDimitry Andric CommandArgumentEntry arg2; 5200b57cec5SDimitry Andric CommandArgumentData var_name_arg; 5210b57cec5SDimitry Andric CommandArgumentData index_arg; 5220b57cec5SDimitry Andric CommandArgumentData key_arg; 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 5250b57cec5SDimitry Andric var_name_arg.arg_type = eArgTypeSettingVariableName; 5260b57cec5SDimitry Andric var_name_arg.arg_repetition = eArgRepeatPlain; 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 5290b57cec5SDimitry Andric // argument entry. 5300b57cec5SDimitry Andric arg1.push_back(var_name_arg); 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric // Define the first variant of this arg. 5330b57cec5SDimitry Andric index_arg.arg_type = eArgTypeSettingIndex; 5340b57cec5SDimitry Andric index_arg.arg_repetition = eArgRepeatPlain; 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric // Define the second variant of this arg. 5370b57cec5SDimitry Andric key_arg.arg_type = eArgTypeSettingKey; 5380b57cec5SDimitry Andric key_arg.arg_repetition = eArgRepeatPlain; 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric // Push both variants into this arg 5410b57cec5SDimitry Andric arg2.push_back(index_arg); 5420b57cec5SDimitry Andric arg2.push_back(key_arg); 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector. 5450b57cec5SDimitry Andric m_arguments.push_back(arg1); 5460b57cec5SDimitry Andric m_arguments.push_back(arg2); 5470b57cec5SDimitry Andric } 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric ~CommandObjectSettingsRemove() override = default; 5500b57cec5SDimitry Andric 5519dba64beSDimitry Andric bool WantsCompletion() override { return true; } 5529dba64beSDimitry Andric 5539dba64beSDimitry Andric void 5549dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request, 5550b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override { 5560b57cec5SDimitry Andric if (request.GetCursorIndex() < 2) 55706c3fb27SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 55806c3fb27SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, 55906c3fb27SDimitry Andric nullptr); 5600b57cec5SDimitry Andric } 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric protected: 5635f757f3fSDimitry Andric void DoExecute(llvm::StringRef command, 5640b57cec5SDimitry Andric CommandReturnObject &result) override { 5650b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult); 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric Args cmd_args(command); 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric // Process possible options. 5700b57cec5SDimitry Andric if (!ParseOptions(cmd_args, result)) 5715f757f3fSDimitry Andric return; 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric const size_t argc = cmd_args.GetArgumentCount(); 5740b57cec5SDimitry Andric if (argc == 0) { 5759dba64beSDimitry Andric result.AppendError("'settings remove' takes an array or dictionary item, " 5769dba64beSDimitry Andric "or an array followed by one or more indexes, or a " 5770b57cec5SDimitry Andric "dictionary followed by one or more key names to " 5780b57cec5SDimitry Andric "remove"); 5795f757f3fSDimitry Andric return; 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric const char *var_name = cmd_args.GetArgumentAtIndex(0); 5830b57cec5SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) { 5840b57cec5SDimitry Andric result.AppendError( 5859dba64beSDimitry Andric "'settings remove' command requires a valid variable name"); 5865f757f3fSDimitry Andric return; 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric // Split the raw command into var_name and value pair. 5909dba64beSDimitry Andric llvm::StringRef var_value(command); 5919dba64beSDimitry Andric var_value = var_value.split(var_name).second.trim(); 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric Status error(GetDebugger().SetPropertyValue( 5949dba64beSDimitry Andric &m_exe_ctx, eVarSetOperationRemove, var_name, var_value)); 5950b57cec5SDimitry Andric if (error.Fail()) { 5960b57cec5SDimitry Andric result.AppendError(error.AsCString()); 5970b57cec5SDimitry Andric } 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric }; 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric // CommandObjectSettingsReplace 6020b57cec5SDimitry Andric 6030b57cec5SDimitry Andric class CommandObjectSettingsReplace : public CommandObjectRaw { 6040b57cec5SDimitry Andric public: 6050b57cec5SDimitry Andric CommandObjectSettingsReplace(CommandInterpreter &interpreter) 6060b57cec5SDimitry Andric : CommandObjectRaw(interpreter, "settings replace", 6070b57cec5SDimitry Andric "Replace the debugger setting value specified by " 6080b57cec5SDimitry Andric "array index or dictionary key.") { 6090b57cec5SDimitry Andric CommandArgumentEntry arg1; 6100b57cec5SDimitry Andric CommandArgumentEntry arg2; 6110b57cec5SDimitry Andric CommandArgumentEntry arg3; 6120b57cec5SDimitry Andric CommandArgumentData var_name_arg; 6130b57cec5SDimitry Andric CommandArgumentData index_arg; 6140b57cec5SDimitry Andric CommandArgumentData key_arg; 6150b57cec5SDimitry Andric CommandArgumentData value_arg; 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 6180b57cec5SDimitry Andric var_name_arg.arg_type = eArgTypeSettingVariableName; 6190b57cec5SDimitry Andric var_name_arg.arg_repetition = eArgRepeatPlain; 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 6220b57cec5SDimitry Andric // argument entry. 6230b57cec5SDimitry Andric arg1.push_back(var_name_arg); 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric // Define the first (variant of this arg. 6260b57cec5SDimitry Andric index_arg.arg_type = eArgTypeSettingIndex; 6270b57cec5SDimitry Andric index_arg.arg_repetition = eArgRepeatPlain; 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric // Define the second (variant of this arg. 6300b57cec5SDimitry Andric key_arg.arg_type = eArgTypeSettingKey; 6310b57cec5SDimitry Andric key_arg.arg_repetition = eArgRepeatPlain; 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric // Put both variants into this arg 6340b57cec5SDimitry Andric arg2.push_back(index_arg); 6350b57cec5SDimitry Andric arg2.push_back(key_arg); 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 6380b57cec5SDimitry Andric value_arg.arg_type = eArgTypeValue; 6390b57cec5SDimitry Andric value_arg.arg_repetition = eArgRepeatPlain; 6400b57cec5SDimitry Andric 6410b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 6420b57cec5SDimitry Andric // argument entry. 6430b57cec5SDimitry Andric arg3.push_back(value_arg); 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector. 6460b57cec5SDimitry Andric m_arguments.push_back(arg1); 6470b57cec5SDimitry Andric m_arguments.push_back(arg2); 6480b57cec5SDimitry Andric m_arguments.push_back(arg3); 6490b57cec5SDimitry Andric } 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric ~CommandObjectSettingsReplace() override = default; 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric // Overrides base class's behavior where WantsCompletion = 6540b57cec5SDimitry Andric // !WantsRawCommandString. 6550b57cec5SDimitry Andric bool WantsCompletion() override { return true; } 6560b57cec5SDimitry Andric 6579dba64beSDimitry Andric void 6589dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request, 6590b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override { 6600b57cec5SDimitry Andric // Attempting to complete variable name 6610b57cec5SDimitry Andric if (request.GetCursorIndex() < 2) 66206c3fb27SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 66306c3fb27SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, 66406c3fb27SDimitry Andric nullptr); 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric protected: 6685f757f3fSDimitry Andric void DoExecute(llvm::StringRef command, 6690b57cec5SDimitry Andric CommandReturnObject &result) override { 6700b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult); 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric Args cmd_args(command); 6730b57cec5SDimitry Andric const char *var_name = cmd_args.GetArgumentAtIndex(0); 6740b57cec5SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) { 6750b57cec5SDimitry Andric result.AppendError("'settings replace' command requires a valid variable " 6760b57cec5SDimitry Andric "name; No value supplied"); 6775f757f3fSDimitry Andric return; 6780b57cec5SDimitry Andric } 6790b57cec5SDimitry Andric 6800b57cec5SDimitry Andric // Split the raw command into var_name, index_value, and value triple. 6819dba64beSDimitry Andric llvm::StringRef var_value(command); 6829dba64beSDimitry Andric var_value = var_value.split(var_name).second.trim(); 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andric Status error(GetDebugger().SetPropertyValue( 6859dba64beSDimitry Andric &m_exe_ctx, eVarSetOperationReplace, var_name, var_value)); 6860b57cec5SDimitry Andric if (error.Fail()) { 6870b57cec5SDimitry Andric result.AppendError(error.AsCString()); 6880b57cec5SDimitry Andric } else { 6890b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult); 6900b57cec5SDimitry Andric } 6910b57cec5SDimitry Andric } 6920b57cec5SDimitry Andric }; 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric // CommandObjectSettingsInsertBefore 6950b57cec5SDimitry Andric 6960b57cec5SDimitry Andric class CommandObjectSettingsInsertBefore : public CommandObjectRaw { 6970b57cec5SDimitry Andric public: 6980b57cec5SDimitry Andric CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter) 6990b57cec5SDimitry Andric : CommandObjectRaw(interpreter, "settings insert-before", 7000b57cec5SDimitry Andric "Insert one or more values into an debugger array " 7010b57cec5SDimitry Andric "setting immediately before the specified element " 7020b57cec5SDimitry Andric "index.") { 7030b57cec5SDimitry Andric CommandArgumentEntry arg1; 7040b57cec5SDimitry Andric CommandArgumentEntry arg2; 7050b57cec5SDimitry Andric CommandArgumentEntry arg3; 7060b57cec5SDimitry Andric CommandArgumentData var_name_arg; 7070b57cec5SDimitry Andric CommandArgumentData index_arg; 7080b57cec5SDimitry Andric CommandArgumentData value_arg; 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 7110b57cec5SDimitry Andric var_name_arg.arg_type = eArgTypeSettingVariableName; 7120b57cec5SDimitry Andric var_name_arg.arg_repetition = eArgRepeatPlain; 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 7150b57cec5SDimitry Andric // argument entry. 7160b57cec5SDimitry Andric arg1.push_back(var_name_arg); 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric // Define the first (variant of this arg. 7190b57cec5SDimitry Andric index_arg.arg_type = eArgTypeSettingIndex; 7200b57cec5SDimitry Andric index_arg.arg_repetition = eArgRepeatPlain; 7210b57cec5SDimitry Andric 7220b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 7230b57cec5SDimitry Andric // argument entry. 7240b57cec5SDimitry Andric arg2.push_back(index_arg); 7250b57cec5SDimitry Andric 7260b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 7270b57cec5SDimitry Andric value_arg.arg_type = eArgTypeValue; 7280b57cec5SDimitry Andric value_arg.arg_repetition = eArgRepeatPlain; 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 7310b57cec5SDimitry Andric // argument entry. 7320b57cec5SDimitry Andric arg3.push_back(value_arg); 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector. 7350b57cec5SDimitry Andric m_arguments.push_back(arg1); 7360b57cec5SDimitry Andric m_arguments.push_back(arg2); 7370b57cec5SDimitry Andric m_arguments.push_back(arg3); 7380b57cec5SDimitry Andric } 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric ~CommandObjectSettingsInsertBefore() override = default; 7410b57cec5SDimitry Andric 7420b57cec5SDimitry Andric // Overrides base class's behavior where WantsCompletion = 7430b57cec5SDimitry Andric // !WantsRawCommandString. 7440b57cec5SDimitry Andric bool WantsCompletion() override { return true; } 7450b57cec5SDimitry Andric 7469dba64beSDimitry Andric void 7479dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request, 7480b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override { 7490b57cec5SDimitry Andric // Attempting to complete variable name 7500b57cec5SDimitry Andric if (request.GetCursorIndex() < 2) 75106c3fb27SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 75206c3fb27SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, 75306c3fb27SDimitry Andric nullptr); 7540b57cec5SDimitry Andric } 7550b57cec5SDimitry Andric 7560b57cec5SDimitry Andric protected: 7575f757f3fSDimitry Andric void DoExecute(llvm::StringRef command, 7580b57cec5SDimitry Andric CommandReturnObject &result) override { 7590b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult); 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric Args cmd_args(command); 7620b57cec5SDimitry Andric const size_t argc = cmd_args.GetArgumentCount(); 7630b57cec5SDimitry Andric 7640b57cec5SDimitry Andric if (argc < 3) { 7650b57cec5SDimitry Andric result.AppendError("'settings insert-before' takes more arguments"); 7665f757f3fSDimitry Andric return; 7670b57cec5SDimitry Andric } 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric const char *var_name = cmd_args.GetArgumentAtIndex(0); 7700b57cec5SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) { 7710b57cec5SDimitry Andric result.AppendError("'settings insert-before' command requires a valid " 7720b57cec5SDimitry Andric "variable name; No value supplied"); 7735f757f3fSDimitry Andric return; 7740b57cec5SDimitry Andric } 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric // Split the raw command into var_name, index_value, and value triple. 7779dba64beSDimitry Andric llvm::StringRef var_value(command); 7789dba64beSDimitry Andric var_value = var_value.split(var_name).second.trim(); 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric Status error(GetDebugger().SetPropertyValue( 7819dba64beSDimitry Andric &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value)); 7820b57cec5SDimitry Andric if (error.Fail()) { 7830b57cec5SDimitry Andric result.AppendError(error.AsCString()); 7840b57cec5SDimitry Andric } 7850b57cec5SDimitry Andric } 7860b57cec5SDimitry Andric }; 7870b57cec5SDimitry Andric 7880b57cec5SDimitry Andric // CommandObjectSettingInsertAfter 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric class CommandObjectSettingsInsertAfter : public CommandObjectRaw { 7910b57cec5SDimitry Andric public: 7920b57cec5SDimitry Andric CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter) 7930b57cec5SDimitry Andric : CommandObjectRaw(interpreter, "settings insert-after", 7940b57cec5SDimitry Andric "Insert one or more values into a debugger array " 7950b57cec5SDimitry Andric "settings after the specified element index.") { 7960b57cec5SDimitry Andric CommandArgumentEntry arg1; 7970b57cec5SDimitry Andric CommandArgumentEntry arg2; 7980b57cec5SDimitry Andric CommandArgumentEntry arg3; 7990b57cec5SDimitry Andric CommandArgumentData var_name_arg; 8000b57cec5SDimitry Andric CommandArgumentData index_arg; 8010b57cec5SDimitry Andric CommandArgumentData value_arg; 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 8040b57cec5SDimitry Andric var_name_arg.arg_type = eArgTypeSettingVariableName; 8050b57cec5SDimitry Andric var_name_arg.arg_repetition = eArgRepeatPlain; 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 8080b57cec5SDimitry Andric // argument entry. 8090b57cec5SDimitry Andric arg1.push_back(var_name_arg); 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric // Define the first (variant of this arg. 8120b57cec5SDimitry Andric index_arg.arg_type = eArgTypeSettingIndex; 8130b57cec5SDimitry Andric index_arg.arg_repetition = eArgRepeatPlain; 8140b57cec5SDimitry Andric 8150b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 8160b57cec5SDimitry Andric // argument entry. 8170b57cec5SDimitry Andric arg2.push_back(index_arg); 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 8200b57cec5SDimitry Andric value_arg.arg_type = eArgTypeValue; 8210b57cec5SDimitry Andric value_arg.arg_repetition = eArgRepeatPlain; 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 8240b57cec5SDimitry Andric // argument entry. 8250b57cec5SDimitry Andric arg3.push_back(value_arg); 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector. 8280b57cec5SDimitry Andric m_arguments.push_back(arg1); 8290b57cec5SDimitry Andric m_arguments.push_back(arg2); 8300b57cec5SDimitry Andric m_arguments.push_back(arg3); 8310b57cec5SDimitry Andric } 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric ~CommandObjectSettingsInsertAfter() override = default; 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric // Overrides base class's behavior where WantsCompletion = 8360b57cec5SDimitry Andric // !WantsRawCommandString. 8370b57cec5SDimitry Andric bool WantsCompletion() override { return true; } 8380b57cec5SDimitry Andric 8399dba64beSDimitry Andric void 8409dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request, 8410b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override { 8420b57cec5SDimitry Andric // Attempting to complete variable name 8430b57cec5SDimitry Andric if (request.GetCursorIndex() < 2) 84406c3fb27SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 84506c3fb27SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, 84606c3fb27SDimitry Andric nullptr); 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric protected: 8505f757f3fSDimitry Andric void DoExecute(llvm::StringRef command, 8510b57cec5SDimitry Andric CommandReturnObject &result) override { 8520b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult); 8530b57cec5SDimitry Andric 8540b57cec5SDimitry Andric Args cmd_args(command); 8550b57cec5SDimitry Andric const size_t argc = cmd_args.GetArgumentCount(); 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andric if (argc < 3) { 8580b57cec5SDimitry Andric result.AppendError("'settings insert-after' takes more arguments"); 8595f757f3fSDimitry Andric return; 8600b57cec5SDimitry Andric } 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric const char *var_name = cmd_args.GetArgumentAtIndex(0); 8630b57cec5SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) { 8640b57cec5SDimitry Andric result.AppendError("'settings insert-after' command requires a valid " 8650b57cec5SDimitry Andric "variable name; No value supplied"); 8665f757f3fSDimitry Andric return; 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric // Split the raw command into var_name, index_value, and value triple. 8709dba64beSDimitry Andric llvm::StringRef var_value(command); 8719dba64beSDimitry Andric var_value = var_value.split(var_name).second.trim(); 8720b57cec5SDimitry Andric 8730b57cec5SDimitry Andric Status error(GetDebugger().SetPropertyValue( 8749dba64beSDimitry Andric &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value)); 8750b57cec5SDimitry Andric if (error.Fail()) { 8760b57cec5SDimitry Andric result.AppendError(error.AsCString()); 8770b57cec5SDimitry Andric } 8780b57cec5SDimitry Andric } 8790b57cec5SDimitry Andric }; 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric // CommandObjectSettingsAppend 8820b57cec5SDimitry Andric 8830b57cec5SDimitry Andric class CommandObjectSettingsAppend : public CommandObjectRaw { 8840b57cec5SDimitry Andric public: 8850b57cec5SDimitry Andric CommandObjectSettingsAppend(CommandInterpreter &interpreter) 8860b57cec5SDimitry Andric : CommandObjectRaw(interpreter, "settings append", 8870b57cec5SDimitry Andric "Append one or more values to a debugger array, " 8880b57cec5SDimitry Andric "dictionary, or string setting.") { 8890b57cec5SDimitry Andric CommandArgumentEntry arg1; 8900b57cec5SDimitry Andric CommandArgumentEntry arg2; 8910b57cec5SDimitry Andric CommandArgumentData var_name_arg; 8920b57cec5SDimitry Andric CommandArgumentData value_arg; 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 8950b57cec5SDimitry Andric var_name_arg.arg_type = eArgTypeSettingVariableName; 8960b57cec5SDimitry Andric var_name_arg.arg_repetition = eArgRepeatPlain; 8970b57cec5SDimitry Andric 8980b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 8990b57cec5SDimitry Andric // argument entry. 9000b57cec5SDimitry Andric arg1.push_back(var_name_arg); 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric // Define the first (and only) variant of this arg. 9030b57cec5SDimitry Andric value_arg.arg_type = eArgTypeValue; 9040b57cec5SDimitry Andric value_arg.arg_repetition = eArgRepeatPlain; 9050b57cec5SDimitry Andric 9060b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the 9070b57cec5SDimitry Andric // argument entry. 9080b57cec5SDimitry Andric arg2.push_back(value_arg); 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector. 9110b57cec5SDimitry Andric m_arguments.push_back(arg1); 9120b57cec5SDimitry Andric m_arguments.push_back(arg2); 9130b57cec5SDimitry Andric } 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andric ~CommandObjectSettingsAppend() override = default; 9160b57cec5SDimitry Andric 9170b57cec5SDimitry Andric // Overrides base class's behavior where WantsCompletion = 9180b57cec5SDimitry Andric // !WantsRawCommandString. 9190b57cec5SDimitry Andric bool WantsCompletion() override { return true; } 9200b57cec5SDimitry Andric 9219dba64beSDimitry Andric void 9229dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request, 9230b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override { 9240b57cec5SDimitry Andric // Attempting to complete variable name 9250b57cec5SDimitry Andric if (request.GetCursorIndex() < 2) 92606c3fb27SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 92706c3fb27SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, 92806c3fb27SDimitry Andric nullptr); 9290b57cec5SDimitry Andric } 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric protected: 9325f757f3fSDimitry Andric void DoExecute(llvm::StringRef command, 9330b57cec5SDimitry Andric CommandReturnObject &result) override { 9340b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult); 9350b57cec5SDimitry Andric Args cmd_args(command); 9360b57cec5SDimitry Andric const size_t argc = cmd_args.GetArgumentCount(); 9370b57cec5SDimitry Andric 9380b57cec5SDimitry Andric if (argc < 2) { 9390b57cec5SDimitry Andric result.AppendError("'settings append' takes more arguments"); 9405f757f3fSDimitry Andric return; 9410b57cec5SDimitry Andric } 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric const char *var_name = cmd_args.GetArgumentAtIndex(0); 9440b57cec5SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) { 9450b57cec5SDimitry Andric result.AppendError("'settings append' command requires a valid variable " 9460b57cec5SDimitry Andric "name; No value supplied"); 9475f757f3fSDimitry Andric return; 9480b57cec5SDimitry Andric } 9490b57cec5SDimitry Andric 9500b57cec5SDimitry Andric // Do not perform cmd_args.Shift() since StringRef is manipulating the raw 9510b57cec5SDimitry Andric // character string later on. 9520b57cec5SDimitry Andric 9530b57cec5SDimitry Andric // Split the raw command into var_name and value pair. 9549dba64beSDimitry Andric llvm::StringRef var_value(command); 9559dba64beSDimitry Andric var_value = var_value.split(var_name).second.trim(); 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andric Status error(GetDebugger().SetPropertyValue( 9589dba64beSDimitry Andric &m_exe_ctx, eVarSetOperationAppend, var_name, var_value)); 9590b57cec5SDimitry Andric if (error.Fail()) { 9600b57cec5SDimitry Andric result.AppendError(error.AsCString()); 9610b57cec5SDimitry Andric } 9620b57cec5SDimitry Andric } 9630b57cec5SDimitry Andric }; 9640b57cec5SDimitry Andric 9650b57cec5SDimitry Andric // CommandObjectSettingsClear 9665ffd83dbSDimitry Andric #define LLDB_OPTIONS_settings_clear 9675ffd83dbSDimitry Andric #include "CommandOptions.inc" 9680b57cec5SDimitry Andric 9690b57cec5SDimitry Andric class CommandObjectSettingsClear : public CommandObjectParsed { 9700b57cec5SDimitry Andric public: 9710b57cec5SDimitry Andric CommandObjectSettingsClear(CommandInterpreter &interpreter) 9720b57cec5SDimitry Andric : CommandObjectParsed( 9730b57cec5SDimitry Andric interpreter, "settings clear", 9745ffd83dbSDimitry Andric "Clear a debugger setting array, dictionary, or string. " 9755ffd83dbSDimitry Andric "If '-a' option is specified, it clears all settings.", nullptr) { 976*0fca6ea1SDimitry Andric AddSimpleArgumentList(eArgTypeSettingVariableName); 9770b57cec5SDimitry Andric } 9780b57cec5SDimitry Andric 9790b57cec5SDimitry Andric ~CommandObjectSettingsClear() override = default; 9800b57cec5SDimitry Andric 9819dba64beSDimitry Andric void 9829dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request, 9830b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override { 9840b57cec5SDimitry Andric // Attempting to complete variable name 9850b57cec5SDimitry Andric if (request.GetCursorIndex() < 2) 98606c3fb27SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 98706c3fb27SDimitry Andric GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, 98806c3fb27SDimitry Andric nullptr); 9890b57cec5SDimitry Andric } 9900b57cec5SDimitry Andric 9915ffd83dbSDimitry Andric Options *GetOptions() override { return &m_options; } 9925ffd83dbSDimitry Andric 9935ffd83dbSDimitry Andric class CommandOptions : public Options { 9945ffd83dbSDimitry Andric public: 9955ffd83dbSDimitry Andric CommandOptions() = default; 9965ffd83dbSDimitry Andric 9975ffd83dbSDimitry Andric ~CommandOptions() override = default; 9985ffd83dbSDimitry Andric 9995ffd83dbSDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 10005ffd83dbSDimitry Andric ExecutionContext *execution_context) override { 10015ffd83dbSDimitry Andric const int short_option = m_getopt_table[option_idx].val; 10025ffd83dbSDimitry Andric switch (short_option) { 10035ffd83dbSDimitry Andric case 'a': 10045ffd83dbSDimitry Andric m_clear_all = true; 10055ffd83dbSDimitry Andric break; 10065ffd83dbSDimitry Andric default: 10075ffd83dbSDimitry Andric llvm_unreachable("Unimplemented option"); 10085ffd83dbSDimitry Andric } 10095ffd83dbSDimitry Andric return Status(); 10105ffd83dbSDimitry Andric } 10115ffd83dbSDimitry Andric 10125ffd83dbSDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override { 10135ffd83dbSDimitry Andric m_clear_all = false; 10145ffd83dbSDimitry Andric } 10155ffd83dbSDimitry Andric 10165ffd83dbSDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1017bdd1243dSDimitry Andric return llvm::ArrayRef(g_settings_clear_options); 10185ffd83dbSDimitry Andric } 10195ffd83dbSDimitry Andric 10205ffd83dbSDimitry Andric bool m_clear_all = false; 10215ffd83dbSDimitry Andric }; 10225ffd83dbSDimitry Andric 10230b57cec5SDimitry Andric protected: 10245f757f3fSDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override { 10250b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult); 10260b57cec5SDimitry Andric const size_t argc = command.GetArgumentCount(); 10270b57cec5SDimitry Andric 10285ffd83dbSDimitry Andric if (m_options.m_clear_all) { 10295ffd83dbSDimitry Andric if (argc != 0) { 10305ffd83dbSDimitry Andric result.AppendError("'settings clear --all' doesn't take any arguments"); 10315f757f3fSDimitry Andric return; 10325ffd83dbSDimitry Andric } 10335ffd83dbSDimitry Andric GetDebugger().GetValueProperties()->Clear(); 10345f757f3fSDimitry Andric return; 10355ffd83dbSDimitry Andric } 10365ffd83dbSDimitry Andric 10370b57cec5SDimitry Andric if (argc != 1) { 10380b57cec5SDimitry Andric result.AppendError("'settings clear' takes exactly one argument"); 10395f757f3fSDimitry Andric return; 10400b57cec5SDimitry Andric } 10410b57cec5SDimitry Andric 10420b57cec5SDimitry Andric const char *var_name = command.GetArgumentAtIndex(0); 10430b57cec5SDimitry Andric if ((var_name == nullptr) || (var_name[0] == '\0')) { 10440b57cec5SDimitry Andric result.AppendError("'settings clear' command requires a valid variable " 10450b57cec5SDimitry Andric "name; No value supplied"); 10465f757f3fSDimitry Andric return; 10470b57cec5SDimitry Andric } 10480b57cec5SDimitry Andric 10490b57cec5SDimitry Andric Status error(GetDebugger().SetPropertyValue( 10500b57cec5SDimitry Andric &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef())); 10510b57cec5SDimitry Andric if (error.Fail()) { 10520b57cec5SDimitry Andric result.AppendError(error.AsCString()); 10530b57cec5SDimitry Andric } 10540b57cec5SDimitry Andric } 10555ffd83dbSDimitry Andric 10565ffd83dbSDimitry Andric private: 10575ffd83dbSDimitry Andric CommandOptions m_options; 10580b57cec5SDimitry Andric }; 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric // CommandObjectMultiwordSettings 10610b57cec5SDimitry Andric 10620b57cec5SDimitry Andric CommandObjectMultiwordSettings::CommandObjectMultiwordSettings( 10630b57cec5SDimitry Andric CommandInterpreter &interpreter) 10640b57cec5SDimitry Andric : CommandObjectMultiword(interpreter, "settings", 10650b57cec5SDimitry Andric "Commands for managing LLDB settings.", 10660b57cec5SDimitry Andric "settings <subcommand> [<command-options>]") { 10670b57cec5SDimitry Andric LoadSubCommand("set", 10680b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsSet(interpreter))); 10690b57cec5SDimitry Andric LoadSubCommand("show", 10700b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsShow(interpreter))); 10710b57cec5SDimitry Andric LoadSubCommand("list", 10720b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsList(interpreter))); 10730b57cec5SDimitry Andric LoadSubCommand("remove", 10740b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsRemove(interpreter))); 10750b57cec5SDimitry Andric LoadSubCommand("replace", CommandObjectSP( 10760b57cec5SDimitry Andric new CommandObjectSettingsReplace(interpreter))); 10770b57cec5SDimitry Andric LoadSubCommand( 10780b57cec5SDimitry Andric "insert-before", 10790b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter))); 10800b57cec5SDimitry Andric LoadSubCommand( 10810b57cec5SDimitry Andric "insert-after", 10820b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter))); 10830b57cec5SDimitry Andric LoadSubCommand("append", 10840b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsAppend(interpreter))); 10850b57cec5SDimitry Andric LoadSubCommand("clear", 10860b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsClear(interpreter))); 10870b57cec5SDimitry Andric LoadSubCommand("write", 10880b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsWrite(interpreter))); 10890b57cec5SDimitry Andric LoadSubCommand("read", 10900b57cec5SDimitry Andric CommandObjectSP(new CommandObjectSettingsRead(interpreter))); 10910b57cec5SDimitry Andric } 10920b57cec5SDimitry Andric 10930b57cec5SDimitry Andric CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default; 1094