1*dda28197Spatrick //===-- CommandObjectSettings.cpp -----------------------------------------===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9061da546Spatrick #include "CommandObjectSettings.h" 10061da546Spatrick 11061da546Spatrick #include "llvm/ADT/StringRef.h" 12061da546Spatrick 13061da546Spatrick #include "lldb/Host/OptionParser.h" 14061da546Spatrick #include "lldb/Interpreter/CommandCompletions.h" 15061da546Spatrick #include "lldb/Interpreter/CommandInterpreter.h" 16061da546Spatrick #include "lldb/Interpreter/CommandReturnObject.h" 17061da546Spatrick #include "lldb/Interpreter/OptionValueProperties.h" 18061da546Spatrick 19061da546Spatrick using namespace lldb; 20061da546Spatrick using namespace lldb_private; 21061da546Spatrick 22061da546Spatrick // CommandObjectSettingsSet 23061da546Spatrick #define LLDB_OPTIONS_settings_set 24061da546Spatrick #include "CommandOptions.inc" 25061da546Spatrick 26061da546Spatrick class CommandObjectSettingsSet : public CommandObjectRaw { 27061da546Spatrick public: 28061da546Spatrick CommandObjectSettingsSet(CommandInterpreter &interpreter) 29061da546Spatrick : CommandObjectRaw(interpreter, "settings set", 30061da546Spatrick "Set the value of the specified debugger setting."), 31061da546Spatrick m_options() { 32061da546Spatrick CommandArgumentEntry arg1; 33061da546Spatrick CommandArgumentEntry arg2; 34061da546Spatrick CommandArgumentData var_name_arg; 35061da546Spatrick CommandArgumentData value_arg; 36061da546Spatrick 37061da546Spatrick // Define the first (and only) variant of this arg. 38061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 39061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain; 40061da546Spatrick 41061da546Spatrick // There is only one variant this argument could be; put it into the 42061da546Spatrick // argument entry. 43061da546Spatrick arg1.push_back(var_name_arg); 44061da546Spatrick 45061da546Spatrick // Define the first (and only) variant of this arg. 46061da546Spatrick value_arg.arg_type = eArgTypeValue; 47061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain; 48061da546Spatrick 49061da546Spatrick // There is only one variant this argument could be; put it into the 50061da546Spatrick // argument entry. 51061da546Spatrick arg2.push_back(value_arg); 52061da546Spatrick 53061da546Spatrick // Push the data for the first argument into the m_arguments vector. 54061da546Spatrick m_arguments.push_back(arg1); 55061da546Spatrick m_arguments.push_back(arg2); 56061da546Spatrick 57061da546Spatrick SetHelpLong( 58061da546Spatrick "\nWhen setting a dictionary or array variable, you can set multiple entries \ 59061da546Spatrick at once by giving the values to the set command. For example:" 60061da546Spatrick R"( 61061da546Spatrick 62061da546Spatrick (lldb) settings set target.run-args value1 value2 value3 63061da546Spatrick (lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345 64061da546Spatrick 65061da546Spatrick (lldb) settings show target.run-args 66061da546Spatrick [0]: 'value1' 67061da546Spatrick [1]: 'value2' 68061da546Spatrick [3]: 'value3' 69061da546Spatrick (lldb) settings show target.env-vars 70061da546Spatrick 'MYPATH=~/.:/usr/bin' 71061da546Spatrick 'SOME_ENV_VAR=12345' 72061da546Spatrick 73061da546Spatrick )" 74061da546Spatrick "Warning: The 'set' command re-sets the entire array or dictionary. If you \ 75061da546Spatrick just want to add, remove or update individual values (or add something to \ 76061da546Spatrick the end), use one of the other settings sub-commands: append, replace, \ 77061da546Spatrick insert-before or insert-after."); 78061da546Spatrick } 79061da546Spatrick 80061da546Spatrick ~CommandObjectSettingsSet() override = default; 81061da546Spatrick 82061da546Spatrick // Overrides base class's behavior where WantsCompletion = 83061da546Spatrick // !WantsRawCommandString. 84061da546Spatrick bool WantsCompletion() override { return true; } 85061da546Spatrick 86061da546Spatrick Options *GetOptions() override { return &m_options; } 87061da546Spatrick 88061da546Spatrick class CommandOptions : public Options { 89061da546Spatrick public: 90061da546Spatrick CommandOptions() : Options(), m_global(false) {} 91061da546Spatrick 92061da546Spatrick ~CommandOptions() override = default; 93061da546Spatrick 94061da546Spatrick Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 95061da546Spatrick ExecutionContext *execution_context) override { 96061da546Spatrick Status error; 97061da546Spatrick const int short_option = m_getopt_table[option_idx].val; 98061da546Spatrick 99061da546Spatrick switch (short_option) { 100061da546Spatrick case 'f': 101061da546Spatrick m_force = true; 102061da546Spatrick break; 103061da546Spatrick case 'g': 104061da546Spatrick m_global = true; 105061da546Spatrick break; 106061da546Spatrick default: 107061da546Spatrick llvm_unreachable("Unimplemented option"); 108061da546Spatrick } 109061da546Spatrick 110061da546Spatrick return error; 111061da546Spatrick } 112061da546Spatrick 113061da546Spatrick void OptionParsingStarting(ExecutionContext *execution_context) override { 114061da546Spatrick m_global = false; 115061da546Spatrick m_force = false; 116061da546Spatrick } 117061da546Spatrick 118061da546Spatrick llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 119061da546Spatrick return llvm::makeArrayRef(g_settings_set_options); 120061da546Spatrick } 121061da546Spatrick 122061da546Spatrick // Instance variables to hold the values for command options. 123061da546Spatrick bool m_global; 124061da546Spatrick bool m_force; 125061da546Spatrick }; 126061da546Spatrick 127061da546Spatrick void 128061da546Spatrick HandleArgumentCompletion(CompletionRequest &request, 129061da546Spatrick OptionElementVector &opt_element_vector) override { 130061da546Spatrick 131061da546Spatrick const size_t argc = request.GetParsedLine().GetArgumentCount(); 132061da546Spatrick const char *arg = nullptr; 133061da546Spatrick size_t setting_var_idx; 134061da546Spatrick for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) { 135061da546Spatrick arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); 136061da546Spatrick if (arg && arg[0] != '-') 137061da546Spatrick break; // We found our setting variable name index 138061da546Spatrick } 139061da546Spatrick if (request.GetCursorIndex() == setting_var_idx) { 140061da546Spatrick // Attempting to complete setting variable name 141061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks( 142061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, 143061da546Spatrick request, nullptr); 144061da546Spatrick return; 145061da546Spatrick } 146061da546Spatrick arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()); 147061da546Spatrick 148061da546Spatrick if (!arg) 149061da546Spatrick return; 150061da546Spatrick 151061da546Spatrick // Complete option name 152061da546Spatrick if (arg[0] != '-') 153061da546Spatrick return; 154061da546Spatrick 155061da546Spatrick // Complete setting value 156061da546Spatrick const char *setting_var_name = 157061da546Spatrick request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); 158061da546Spatrick Status error; 159061da546Spatrick lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue( 160061da546Spatrick &m_exe_ctx, setting_var_name, false, error)); 161061da546Spatrick if (!value_sp) 162061da546Spatrick return; 163061da546Spatrick value_sp->AutoComplete(m_interpreter, request); 164061da546Spatrick } 165061da546Spatrick 166061da546Spatrick protected: 167061da546Spatrick bool DoExecute(llvm::StringRef command, 168061da546Spatrick CommandReturnObject &result) override { 169061da546Spatrick Args cmd_args(command); 170061da546Spatrick 171061da546Spatrick // Process possible options. 172061da546Spatrick if (!ParseOptions(cmd_args, result)) 173061da546Spatrick return false; 174061da546Spatrick 175061da546Spatrick const size_t min_argc = m_options.m_force ? 1 : 2; 176061da546Spatrick const size_t argc = cmd_args.GetArgumentCount(); 177061da546Spatrick 178061da546Spatrick if ((argc < min_argc) && (!m_options.m_global)) { 179061da546Spatrick result.AppendError("'settings set' takes more arguments"); 180061da546Spatrick result.SetStatus(eReturnStatusFailed); 181061da546Spatrick return false; 182061da546Spatrick } 183061da546Spatrick 184061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0); 185061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) { 186061da546Spatrick result.AppendError( 187061da546Spatrick "'settings set' command requires a valid variable name"); 188061da546Spatrick result.SetStatus(eReturnStatusFailed); 189061da546Spatrick return false; 190061da546Spatrick } 191061da546Spatrick 192061da546Spatrick // A missing value corresponds to clearing the setting when "force" is 193061da546Spatrick // specified. 194061da546Spatrick if (argc == 1 && m_options.m_force) { 195061da546Spatrick Status error(GetDebugger().SetPropertyValue( 196061da546Spatrick &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef())); 197061da546Spatrick if (error.Fail()) { 198061da546Spatrick result.AppendError(error.AsCString()); 199061da546Spatrick result.SetStatus(eReturnStatusFailed); 200061da546Spatrick return false; 201061da546Spatrick } 202061da546Spatrick return result.Succeeded(); 203061da546Spatrick } 204061da546Spatrick 205061da546Spatrick // Split the raw command into var_name and value pair. 206061da546Spatrick llvm::StringRef var_value(command); 207061da546Spatrick var_value = var_value.split(var_name).second.ltrim(); 208061da546Spatrick 209061da546Spatrick Status error; 210061da546Spatrick if (m_options.m_global) 211061da546Spatrick error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign, 212061da546Spatrick var_name, var_value); 213061da546Spatrick 214061da546Spatrick if (error.Success()) { 215061da546Spatrick // FIXME this is the same issue as the one in commands script import 216061da546Spatrick // we could be setting target.load-script-from-symbol-file which would 217061da546Spatrick // cause Python scripts to be loaded, which could run LLDB commands (e.g. 218061da546Spatrick // settings set target.process.python-os-plugin-path) and cause a crash 219061da546Spatrick // if we did not clear the command's exe_ctx first 220061da546Spatrick ExecutionContext exe_ctx(m_exe_ctx); 221061da546Spatrick m_exe_ctx.Clear(); 222061da546Spatrick error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign, 223061da546Spatrick var_name, var_value); 224061da546Spatrick } 225061da546Spatrick 226061da546Spatrick if (error.Fail()) { 227061da546Spatrick result.AppendError(error.AsCString()); 228061da546Spatrick result.SetStatus(eReturnStatusFailed); 229061da546Spatrick return false; 230061da546Spatrick } else { 231061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishResult); 232061da546Spatrick } 233061da546Spatrick 234061da546Spatrick return result.Succeeded(); 235061da546Spatrick } 236061da546Spatrick 237061da546Spatrick private: 238061da546Spatrick CommandOptions m_options; 239061da546Spatrick }; 240061da546Spatrick 241061da546Spatrick // CommandObjectSettingsShow -- Show current values 242061da546Spatrick 243061da546Spatrick class CommandObjectSettingsShow : public CommandObjectParsed { 244061da546Spatrick public: 245061da546Spatrick CommandObjectSettingsShow(CommandInterpreter &interpreter) 246061da546Spatrick : CommandObjectParsed(interpreter, "settings show", 247061da546Spatrick "Show matching debugger settings and their current " 248061da546Spatrick "values. Defaults to showing all settings.", 249061da546Spatrick nullptr) { 250061da546Spatrick CommandArgumentEntry arg1; 251061da546Spatrick CommandArgumentData var_name_arg; 252061da546Spatrick 253061da546Spatrick // Define the first (and only) variant of this arg. 254061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 255061da546Spatrick var_name_arg.arg_repetition = eArgRepeatOptional; 256061da546Spatrick 257061da546Spatrick // There is only one variant this argument could be; put it into the 258061da546Spatrick // argument entry. 259061da546Spatrick arg1.push_back(var_name_arg); 260061da546Spatrick 261061da546Spatrick // Push the data for the first argument into the m_arguments vector. 262061da546Spatrick m_arguments.push_back(arg1); 263061da546Spatrick } 264061da546Spatrick 265061da546Spatrick ~CommandObjectSettingsShow() override = default; 266061da546Spatrick 267061da546Spatrick void 268061da546Spatrick HandleArgumentCompletion(CompletionRequest &request, 269061da546Spatrick OptionElementVector &opt_element_vector) override { 270061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks( 271061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, 272061da546Spatrick request, nullptr); 273061da546Spatrick } 274061da546Spatrick 275061da546Spatrick protected: 276061da546Spatrick bool DoExecute(Args &args, CommandReturnObject &result) override { 277061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishResult); 278061da546Spatrick 279061da546Spatrick if (!args.empty()) { 280061da546Spatrick for (const auto &arg : args) { 281061da546Spatrick Status error(GetDebugger().DumpPropertyValue( 282061da546Spatrick &m_exe_ctx, result.GetOutputStream(), arg.ref(), 283061da546Spatrick OptionValue::eDumpGroupValue)); 284061da546Spatrick if (error.Success()) { 285061da546Spatrick result.GetOutputStream().EOL(); 286061da546Spatrick } else { 287061da546Spatrick result.AppendError(error.AsCString()); 288061da546Spatrick result.SetStatus(eReturnStatusFailed); 289061da546Spatrick } 290061da546Spatrick } 291061da546Spatrick } else { 292061da546Spatrick GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(), 293061da546Spatrick OptionValue::eDumpGroupValue); 294061da546Spatrick } 295061da546Spatrick 296061da546Spatrick return result.Succeeded(); 297061da546Spatrick } 298061da546Spatrick }; 299061da546Spatrick 300061da546Spatrick // CommandObjectSettingsWrite -- Write settings to file 301061da546Spatrick #define LLDB_OPTIONS_settings_write 302061da546Spatrick #include "CommandOptions.inc" 303061da546Spatrick 304061da546Spatrick class CommandObjectSettingsWrite : public CommandObjectParsed { 305061da546Spatrick public: 306061da546Spatrick CommandObjectSettingsWrite(CommandInterpreter &interpreter) 307061da546Spatrick : CommandObjectParsed( 308061da546Spatrick interpreter, "settings export", 309061da546Spatrick "Write matching debugger settings and their " 310061da546Spatrick "current values to a file that can be read in with " 311061da546Spatrick "\"settings read\". Defaults to writing all settings.", 312061da546Spatrick nullptr), 313061da546Spatrick m_options() { 314061da546Spatrick CommandArgumentEntry arg1; 315061da546Spatrick CommandArgumentData var_name_arg; 316061da546Spatrick 317061da546Spatrick // Define the first (and only) variant of this arg. 318061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 319061da546Spatrick var_name_arg.arg_repetition = eArgRepeatOptional; 320061da546Spatrick 321061da546Spatrick // There is only one variant this argument could be; put it into the 322061da546Spatrick // argument entry. 323061da546Spatrick arg1.push_back(var_name_arg); 324061da546Spatrick 325061da546Spatrick // Push the data for the first argument into the m_arguments vector. 326061da546Spatrick m_arguments.push_back(arg1); 327061da546Spatrick } 328061da546Spatrick 329061da546Spatrick ~CommandObjectSettingsWrite() override = default; 330061da546Spatrick 331061da546Spatrick Options *GetOptions() override { return &m_options; } 332061da546Spatrick 333061da546Spatrick class CommandOptions : public Options { 334061da546Spatrick public: 335061da546Spatrick CommandOptions() : Options() {} 336061da546Spatrick 337061da546Spatrick ~CommandOptions() override = default; 338061da546Spatrick 339061da546Spatrick Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 340061da546Spatrick ExecutionContext *execution_context) override { 341061da546Spatrick Status error; 342061da546Spatrick const int short_option = m_getopt_table[option_idx].val; 343061da546Spatrick 344061da546Spatrick switch (short_option) { 345061da546Spatrick case 'f': 346*dda28197Spatrick m_filename.assign(std::string(option_arg)); 347061da546Spatrick break; 348061da546Spatrick case 'a': 349061da546Spatrick m_append = true; 350061da546Spatrick break; 351061da546Spatrick default: 352061da546Spatrick llvm_unreachable("Unimplemented option"); 353061da546Spatrick } 354061da546Spatrick 355061da546Spatrick return error; 356061da546Spatrick } 357061da546Spatrick 358061da546Spatrick void OptionParsingStarting(ExecutionContext *execution_context) override { 359061da546Spatrick m_filename.clear(); 360061da546Spatrick m_append = false; 361061da546Spatrick } 362061da546Spatrick 363061da546Spatrick llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 364061da546Spatrick return llvm::makeArrayRef(g_settings_write_options); 365061da546Spatrick } 366061da546Spatrick 367061da546Spatrick // Instance variables to hold the values for command options. 368061da546Spatrick std::string m_filename; 369061da546Spatrick bool m_append = false; 370061da546Spatrick }; 371061da546Spatrick 372061da546Spatrick protected: 373061da546Spatrick bool DoExecute(Args &args, CommandReturnObject &result) override { 374061da546Spatrick FileSpec file_spec(m_options.m_filename); 375061da546Spatrick FileSystem::Instance().Resolve(file_spec); 376061da546Spatrick std::string path(file_spec.GetPath()); 377061da546Spatrick auto options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; 378061da546Spatrick if (m_options.m_append) 379061da546Spatrick options |= File::eOpenOptionAppend; 380061da546Spatrick else 381061da546Spatrick options |= File::eOpenOptionTruncate; 382061da546Spatrick 383061da546Spatrick StreamFile out_file(path.c_str(), options, 384061da546Spatrick lldb::eFilePermissionsFileDefault); 385061da546Spatrick 386061da546Spatrick if (!out_file.GetFile().IsValid()) { 387061da546Spatrick result.AppendErrorWithFormat("%s: unable to write to file", path.c_str()); 388061da546Spatrick result.SetStatus(eReturnStatusFailed); 389061da546Spatrick return false; 390061da546Spatrick } 391061da546Spatrick 392061da546Spatrick // Exporting should not be context sensitive. 393061da546Spatrick ExecutionContext clean_ctx; 394061da546Spatrick 395061da546Spatrick if (args.empty()) { 396061da546Spatrick GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file, 397061da546Spatrick OptionValue::eDumpGroupExport); 398061da546Spatrick return result.Succeeded(); 399061da546Spatrick } 400061da546Spatrick 401061da546Spatrick for (const auto &arg : args) { 402061da546Spatrick Status error(GetDebugger().DumpPropertyValue( 403061da546Spatrick &clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport)); 404061da546Spatrick if (!error.Success()) { 405061da546Spatrick result.AppendError(error.AsCString()); 406061da546Spatrick result.SetStatus(eReturnStatusFailed); 407061da546Spatrick } 408061da546Spatrick } 409061da546Spatrick 410061da546Spatrick return result.Succeeded(); 411061da546Spatrick } 412061da546Spatrick 413061da546Spatrick private: 414061da546Spatrick CommandOptions m_options; 415061da546Spatrick }; 416061da546Spatrick 417061da546Spatrick // CommandObjectSettingsRead -- Read settings from file 418061da546Spatrick #define LLDB_OPTIONS_settings_read 419061da546Spatrick #include "CommandOptions.inc" 420061da546Spatrick 421061da546Spatrick class CommandObjectSettingsRead : public CommandObjectParsed { 422061da546Spatrick public: 423061da546Spatrick CommandObjectSettingsRead(CommandInterpreter &interpreter) 424061da546Spatrick : CommandObjectParsed( 425061da546Spatrick interpreter, "settings read", 426061da546Spatrick "Read settings previously saved to a file with \"settings write\".", 427061da546Spatrick nullptr), 428061da546Spatrick m_options() {} 429061da546Spatrick 430061da546Spatrick ~CommandObjectSettingsRead() override = default; 431061da546Spatrick 432061da546Spatrick Options *GetOptions() override { return &m_options; } 433061da546Spatrick 434061da546Spatrick class CommandOptions : public Options { 435061da546Spatrick public: 436061da546Spatrick CommandOptions() : Options() {} 437061da546Spatrick 438061da546Spatrick ~CommandOptions() override = default; 439061da546Spatrick 440061da546Spatrick Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 441061da546Spatrick ExecutionContext *execution_context) override { 442061da546Spatrick Status error; 443061da546Spatrick const int short_option = m_getopt_table[option_idx].val; 444061da546Spatrick 445061da546Spatrick switch (short_option) { 446061da546Spatrick case 'f': 447*dda28197Spatrick m_filename.assign(std::string(option_arg)); 448061da546Spatrick break; 449061da546Spatrick default: 450061da546Spatrick llvm_unreachable("Unimplemented option"); 451061da546Spatrick } 452061da546Spatrick 453061da546Spatrick return error; 454061da546Spatrick } 455061da546Spatrick 456061da546Spatrick void OptionParsingStarting(ExecutionContext *execution_context) override { 457061da546Spatrick m_filename.clear(); 458061da546Spatrick } 459061da546Spatrick 460061da546Spatrick llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 461061da546Spatrick return llvm::makeArrayRef(g_settings_read_options); 462061da546Spatrick } 463061da546Spatrick 464061da546Spatrick // Instance variables to hold the values for command options. 465061da546Spatrick std::string m_filename; 466061da546Spatrick }; 467061da546Spatrick 468061da546Spatrick protected: 469061da546Spatrick bool DoExecute(Args &command, CommandReturnObject &result) override { 470061da546Spatrick FileSpec file(m_options.m_filename); 471061da546Spatrick FileSystem::Instance().Resolve(file); 472061da546Spatrick ExecutionContext clean_ctx; 473061da546Spatrick CommandInterpreterRunOptions options; 474061da546Spatrick options.SetAddToHistory(false); 475061da546Spatrick options.SetEchoCommands(false); 476061da546Spatrick options.SetPrintResults(true); 477061da546Spatrick options.SetPrintErrors(true); 478061da546Spatrick options.SetStopOnError(false); 479061da546Spatrick m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result); 480061da546Spatrick return result.Succeeded(); 481061da546Spatrick } 482061da546Spatrick 483061da546Spatrick private: 484061da546Spatrick CommandOptions m_options; 485061da546Spatrick }; 486061da546Spatrick 487061da546Spatrick // CommandObjectSettingsList -- List settable variables 488061da546Spatrick 489061da546Spatrick class CommandObjectSettingsList : public CommandObjectParsed { 490061da546Spatrick public: 491061da546Spatrick CommandObjectSettingsList(CommandInterpreter &interpreter) 492061da546Spatrick : CommandObjectParsed(interpreter, "settings list", 493061da546Spatrick "List and describe matching debugger settings. " 494061da546Spatrick "Defaults to all listing all settings.", 495061da546Spatrick nullptr) { 496061da546Spatrick CommandArgumentEntry arg; 497061da546Spatrick CommandArgumentData var_name_arg; 498061da546Spatrick CommandArgumentData prefix_name_arg; 499061da546Spatrick 500061da546Spatrick // Define the first variant of this arg. 501061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 502061da546Spatrick var_name_arg.arg_repetition = eArgRepeatOptional; 503061da546Spatrick 504061da546Spatrick // Define the second variant of this arg. 505061da546Spatrick prefix_name_arg.arg_type = eArgTypeSettingPrefix; 506061da546Spatrick prefix_name_arg.arg_repetition = eArgRepeatOptional; 507061da546Spatrick 508061da546Spatrick arg.push_back(var_name_arg); 509061da546Spatrick arg.push_back(prefix_name_arg); 510061da546Spatrick 511061da546Spatrick // Push the data for the first argument into the m_arguments vector. 512061da546Spatrick m_arguments.push_back(arg); 513061da546Spatrick } 514061da546Spatrick 515061da546Spatrick ~CommandObjectSettingsList() override = default; 516061da546Spatrick 517061da546Spatrick void 518061da546Spatrick HandleArgumentCompletion(CompletionRequest &request, 519061da546Spatrick OptionElementVector &opt_element_vector) override { 520061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks( 521061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, 522061da546Spatrick request, nullptr); 523061da546Spatrick } 524061da546Spatrick 525061da546Spatrick protected: 526061da546Spatrick bool DoExecute(Args &args, CommandReturnObject &result) override { 527061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishResult); 528061da546Spatrick 529061da546Spatrick const bool will_modify = false; 530061da546Spatrick const size_t argc = args.GetArgumentCount(); 531061da546Spatrick if (argc > 0) { 532061da546Spatrick const bool dump_qualified_name = true; 533061da546Spatrick 534*dda28197Spatrick for (const Args::ArgEntry &arg : args) { 535*dda28197Spatrick const char *property_path = arg.c_str(); 536061da546Spatrick 537061da546Spatrick const Property *property = 538061da546Spatrick GetDebugger().GetValueProperties()->GetPropertyAtPath( 539061da546Spatrick &m_exe_ctx, will_modify, property_path); 540061da546Spatrick 541061da546Spatrick if (property) { 542061da546Spatrick property->DumpDescription(m_interpreter, result.GetOutputStream(), 0, 543061da546Spatrick dump_qualified_name); 544061da546Spatrick } else { 545061da546Spatrick result.AppendErrorWithFormat("invalid property path '%s'", 546061da546Spatrick property_path); 547061da546Spatrick result.SetStatus(eReturnStatusFailed); 548061da546Spatrick } 549061da546Spatrick } 550061da546Spatrick } else { 551061da546Spatrick GetDebugger().DumpAllDescriptions(m_interpreter, 552061da546Spatrick result.GetOutputStream()); 553061da546Spatrick } 554061da546Spatrick 555061da546Spatrick return result.Succeeded(); 556061da546Spatrick } 557061da546Spatrick }; 558061da546Spatrick 559061da546Spatrick // CommandObjectSettingsRemove 560061da546Spatrick 561061da546Spatrick class CommandObjectSettingsRemove : public CommandObjectRaw { 562061da546Spatrick public: 563061da546Spatrick CommandObjectSettingsRemove(CommandInterpreter &interpreter) 564061da546Spatrick : CommandObjectRaw(interpreter, "settings remove", 565061da546Spatrick "Remove a value from a setting, specified by array " 566061da546Spatrick "index or dictionary key.") { 567061da546Spatrick CommandArgumentEntry arg1; 568061da546Spatrick CommandArgumentEntry arg2; 569061da546Spatrick CommandArgumentData var_name_arg; 570061da546Spatrick CommandArgumentData index_arg; 571061da546Spatrick CommandArgumentData key_arg; 572061da546Spatrick 573061da546Spatrick // Define the first (and only) variant of this arg. 574061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 575061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain; 576061da546Spatrick 577061da546Spatrick // There is only one variant this argument could be; put it into the 578061da546Spatrick // argument entry. 579061da546Spatrick arg1.push_back(var_name_arg); 580061da546Spatrick 581061da546Spatrick // Define the first variant of this arg. 582061da546Spatrick index_arg.arg_type = eArgTypeSettingIndex; 583061da546Spatrick index_arg.arg_repetition = eArgRepeatPlain; 584061da546Spatrick 585061da546Spatrick // Define the second variant of this arg. 586061da546Spatrick key_arg.arg_type = eArgTypeSettingKey; 587061da546Spatrick key_arg.arg_repetition = eArgRepeatPlain; 588061da546Spatrick 589061da546Spatrick // Push both variants into this arg 590061da546Spatrick arg2.push_back(index_arg); 591061da546Spatrick arg2.push_back(key_arg); 592061da546Spatrick 593061da546Spatrick // Push the data for the first argument into the m_arguments vector. 594061da546Spatrick m_arguments.push_back(arg1); 595061da546Spatrick m_arguments.push_back(arg2); 596061da546Spatrick } 597061da546Spatrick 598061da546Spatrick ~CommandObjectSettingsRemove() override = default; 599061da546Spatrick 600061da546Spatrick bool WantsCompletion() override { return true; } 601061da546Spatrick 602061da546Spatrick void 603061da546Spatrick HandleArgumentCompletion(CompletionRequest &request, 604061da546Spatrick OptionElementVector &opt_element_vector) override { 605061da546Spatrick if (request.GetCursorIndex() < 2) 606061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks( 607061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, 608061da546Spatrick request, nullptr); 609061da546Spatrick } 610061da546Spatrick 611061da546Spatrick protected: 612061da546Spatrick bool DoExecute(llvm::StringRef command, 613061da546Spatrick CommandReturnObject &result) override { 614061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult); 615061da546Spatrick 616061da546Spatrick Args cmd_args(command); 617061da546Spatrick 618061da546Spatrick // Process possible options. 619061da546Spatrick if (!ParseOptions(cmd_args, result)) 620061da546Spatrick return false; 621061da546Spatrick 622061da546Spatrick const size_t argc = cmd_args.GetArgumentCount(); 623061da546Spatrick if (argc == 0) { 624061da546Spatrick result.AppendError("'settings remove' takes an array or dictionary item, " 625061da546Spatrick "or an array followed by one or more indexes, or a " 626061da546Spatrick "dictionary followed by one or more key names to " 627061da546Spatrick "remove"); 628061da546Spatrick result.SetStatus(eReturnStatusFailed); 629061da546Spatrick return false; 630061da546Spatrick } 631061da546Spatrick 632061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0); 633061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) { 634061da546Spatrick result.AppendError( 635061da546Spatrick "'settings remove' command requires a valid variable name"); 636061da546Spatrick result.SetStatus(eReturnStatusFailed); 637061da546Spatrick return false; 638061da546Spatrick } 639061da546Spatrick 640061da546Spatrick // Split the raw command into var_name and value pair. 641061da546Spatrick llvm::StringRef var_value(command); 642061da546Spatrick var_value = var_value.split(var_name).second.trim(); 643061da546Spatrick 644061da546Spatrick Status error(GetDebugger().SetPropertyValue( 645061da546Spatrick &m_exe_ctx, eVarSetOperationRemove, var_name, var_value)); 646061da546Spatrick if (error.Fail()) { 647061da546Spatrick result.AppendError(error.AsCString()); 648061da546Spatrick result.SetStatus(eReturnStatusFailed); 649061da546Spatrick return false; 650061da546Spatrick } 651061da546Spatrick 652061da546Spatrick return result.Succeeded(); 653061da546Spatrick } 654061da546Spatrick }; 655061da546Spatrick 656061da546Spatrick // CommandObjectSettingsReplace 657061da546Spatrick 658061da546Spatrick class CommandObjectSettingsReplace : public CommandObjectRaw { 659061da546Spatrick public: 660061da546Spatrick CommandObjectSettingsReplace(CommandInterpreter &interpreter) 661061da546Spatrick : CommandObjectRaw(interpreter, "settings replace", 662061da546Spatrick "Replace the debugger setting value specified by " 663061da546Spatrick "array index or dictionary key.") { 664061da546Spatrick CommandArgumentEntry arg1; 665061da546Spatrick CommandArgumentEntry arg2; 666061da546Spatrick CommandArgumentEntry arg3; 667061da546Spatrick CommandArgumentData var_name_arg; 668061da546Spatrick CommandArgumentData index_arg; 669061da546Spatrick CommandArgumentData key_arg; 670061da546Spatrick CommandArgumentData value_arg; 671061da546Spatrick 672061da546Spatrick // Define the first (and only) variant of this arg. 673061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 674061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain; 675061da546Spatrick 676061da546Spatrick // There is only one variant this argument could be; put it into the 677061da546Spatrick // argument entry. 678061da546Spatrick arg1.push_back(var_name_arg); 679061da546Spatrick 680061da546Spatrick // Define the first (variant of this arg. 681061da546Spatrick index_arg.arg_type = eArgTypeSettingIndex; 682061da546Spatrick index_arg.arg_repetition = eArgRepeatPlain; 683061da546Spatrick 684061da546Spatrick // Define the second (variant of this arg. 685061da546Spatrick key_arg.arg_type = eArgTypeSettingKey; 686061da546Spatrick key_arg.arg_repetition = eArgRepeatPlain; 687061da546Spatrick 688061da546Spatrick // Put both variants into this arg 689061da546Spatrick arg2.push_back(index_arg); 690061da546Spatrick arg2.push_back(key_arg); 691061da546Spatrick 692061da546Spatrick // Define the first (and only) variant of this arg. 693061da546Spatrick value_arg.arg_type = eArgTypeValue; 694061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain; 695061da546Spatrick 696061da546Spatrick // There is only one variant this argument could be; put it into the 697061da546Spatrick // argument entry. 698061da546Spatrick arg3.push_back(value_arg); 699061da546Spatrick 700061da546Spatrick // Push the data for the first argument into the m_arguments vector. 701061da546Spatrick m_arguments.push_back(arg1); 702061da546Spatrick m_arguments.push_back(arg2); 703061da546Spatrick m_arguments.push_back(arg3); 704061da546Spatrick } 705061da546Spatrick 706061da546Spatrick ~CommandObjectSettingsReplace() override = default; 707061da546Spatrick 708061da546Spatrick // Overrides base class's behavior where WantsCompletion = 709061da546Spatrick // !WantsRawCommandString. 710061da546Spatrick bool WantsCompletion() override { return true; } 711061da546Spatrick 712061da546Spatrick void 713061da546Spatrick HandleArgumentCompletion(CompletionRequest &request, 714061da546Spatrick OptionElementVector &opt_element_vector) override { 715061da546Spatrick // Attempting to complete variable name 716061da546Spatrick if (request.GetCursorIndex() < 2) 717061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks( 718061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, 719061da546Spatrick request, nullptr); 720061da546Spatrick } 721061da546Spatrick 722061da546Spatrick protected: 723061da546Spatrick bool DoExecute(llvm::StringRef command, 724061da546Spatrick CommandReturnObject &result) override { 725061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult); 726061da546Spatrick 727061da546Spatrick Args cmd_args(command); 728061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0); 729061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) { 730061da546Spatrick result.AppendError("'settings replace' command requires a valid variable " 731061da546Spatrick "name; No value supplied"); 732061da546Spatrick result.SetStatus(eReturnStatusFailed); 733061da546Spatrick return false; 734061da546Spatrick } 735061da546Spatrick 736061da546Spatrick // Split the raw command into var_name, index_value, and value triple. 737061da546Spatrick llvm::StringRef var_value(command); 738061da546Spatrick var_value = var_value.split(var_name).second.trim(); 739061da546Spatrick 740061da546Spatrick Status error(GetDebugger().SetPropertyValue( 741061da546Spatrick &m_exe_ctx, eVarSetOperationReplace, var_name, var_value)); 742061da546Spatrick if (error.Fail()) { 743061da546Spatrick result.AppendError(error.AsCString()); 744061da546Spatrick result.SetStatus(eReturnStatusFailed); 745061da546Spatrick return false; 746061da546Spatrick } else { 747061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult); 748061da546Spatrick } 749061da546Spatrick 750061da546Spatrick return result.Succeeded(); 751061da546Spatrick } 752061da546Spatrick }; 753061da546Spatrick 754061da546Spatrick // CommandObjectSettingsInsertBefore 755061da546Spatrick 756061da546Spatrick class CommandObjectSettingsInsertBefore : public CommandObjectRaw { 757061da546Spatrick public: 758061da546Spatrick CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter) 759061da546Spatrick : CommandObjectRaw(interpreter, "settings insert-before", 760061da546Spatrick "Insert one or more values into an debugger array " 761061da546Spatrick "setting immediately before the specified element " 762061da546Spatrick "index.") { 763061da546Spatrick CommandArgumentEntry arg1; 764061da546Spatrick CommandArgumentEntry arg2; 765061da546Spatrick CommandArgumentEntry arg3; 766061da546Spatrick CommandArgumentData var_name_arg; 767061da546Spatrick CommandArgumentData index_arg; 768061da546Spatrick CommandArgumentData value_arg; 769061da546Spatrick 770061da546Spatrick // Define the first (and only) variant of this arg. 771061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 772061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain; 773061da546Spatrick 774061da546Spatrick // There is only one variant this argument could be; put it into the 775061da546Spatrick // argument entry. 776061da546Spatrick arg1.push_back(var_name_arg); 777061da546Spatrick 778061da546Spatrick // Define the first (variant of this arg. 779061da546Spatrick index_arg.arg_type = eArgTypeSettingIndex; 780061da546Spatrick index_arg.arg_repetition = eArgRepeatPlain; 781061da546Spatrick 782061da546Spatrick // There is only one variant this argument could be; put it into the 783061da546Spatrick // argument entry. 784061da546Spatrick arg2.push_back(index_arg); 785061da546Spatrick 786061da546Spatrick // Define the first (and only) variant of this arg. 787061da546Spatrick value_arg.arg_type = eArgTypeValue; 788061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain; 789061da546Spatrick 790061da546Spatrick // There is only one variant this argument could be; put it into the 791061da546Spatrick // argument entry. 792061da546Spatrick arg3.push_back(value_arg); 793061da546Spatrick 794061da546Spatrick // Push the data for the first argument into the m_arguments vector. 795061da546Spatrick m_arguments.push_back(arg1); 796061da546Spatrick m_arguments.push_back(arg2); 797061da546Spatrick m_arguments.push_back(arg3); 798061da546Spatrick } 799061da546Spatrick 800061da546Spatrick ~CommandObjectSettingsInsertBefore() override = default; 801061da546Spatrick 802061da546Spatrick // Overrides base class's behavior where WantsCompletion = 803061da546Spatrick // !WantsRawCommandString. 804061da546Spatrick bool WantsCompletion() override { return true; } 805061da546Spatrick 806061da546Spatrick void 807061da546Spatrick HandleArgumentCompletion(CompletionRequest &request, 808061da546Spatrick OptionElementVector &opt_element_vector) override { 809061da546Spatrick // Attempting to complete variable name 810061da546Spatrick if (request.GetCursorIndex() < 2) 811061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks( 812061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, 813061da546Spatrick request, nullptr); 814061da546Spatrick } 815061da546Spatrick 816061da546Spatrick protected: 817061da546Spatrick bool DoExecute(llvm::StringRef command, 818061da546Spatrick CommandReturnObject &result) override { 819061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult); 820061da546Spatrick 821061da546Spatrick Args cmd_args(command); 822061da546Spatrick const size_t argc = cmd_args.GetArgumentCount(); 823061da546Spatrick 824061da546Spatrick if (argc < 3) { 825061da546Spatrick result.AppendError("'settings insert-before' takes more arguments"); 826061da546Spatrick result.SetStatus(eReturnStatusFailed); 827061da546Spatrick return false; 828061da546Spatrick } 829061da546Spatrick 830061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0); 831061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) { 832061da546Spatrick result.AppendError("'settings insert-before' command requires a valid " 833061da546Spatrick "variable name; No value supplied"); 834061da546Spatrick result.SetStatus(eReturnStatusFailed); 835061da546Spatrick return false; 836061da546Spatrick } 837061da546Spatrick 838061da546Spatrick // Split the raw command into var_name, index_value, and value triple. 839061da546Spatrick llvm::StringRef var_value(command); 840061da546Spatrick var_value = var_value.split(var_name).second.trim(); 841061da546Spatrick 842061da546Spatrick Status error(GetDebugger().SetPropertyValue( 843061da546Spatrick &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value)); 844061da546Spatrick if (error.Fail()) { 845061da546Spatrick result.AppendError(error.AsCString()); 846061da546Spatrick result.SetStatus(eReturnStatusFailed); 847061da546Spatrick return false; 848061da546Spatrick } 849061da546Spatrick 850061da546Spatrick return result.Succeeded(); 851061da546Spatrick } 852061da546Spatrick }; 853061da546Spatrick 854061da546Spatrick // CommandObjectSettingInsertAfter 855061da546Spatrick 856061da546Spatrick class CommandObjectSettingsInsertAfter : public CommandObjectRaw { 857061da546Spatrick public: 858061da546Spatrick CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter) 859061da546Spatrick : CommandObjectRaw(interpreter, "settings insert-after", 860061da546Spatrick "Insert one or more values into a debugger array " 861061da546Spatrick "settings after the specified element index.") { 862061da546Spatrick CommandArgumentEntry arg1; 863061da546Spatrick CommandArgumentEntry arg2; 864061da546Spatrick CommandArgumentEntry arg3; 865061da546Spatrick CommandArgumentData var_name_arg; 866061da546Spatrick CommandArgumentData index_arg; 867061da546Spatrick CommandArgumentData value_arg; 868061da546Spatrick 869061da546Spatrick // Define the first (and only) variant of this arg. 870061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 871061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain; 872061da546Spatrick 873061da546Spatrick // There is only one variant this argument could be; put it into the 874061da546Spatrick // argument entry. 875061da546Spatrick arg1.push_back(var_name_arg); 876061da546Spatrick 877061da546Spatrick // Define the first (variant of this arg. 878061da546Spatrick index_arg.arg_type = eArgTypeSettingIndex; 879061da546Spatrick index_arg.arg_repetition = eArgRepeatPlain; 880061da546Spatrick 881061da546Spatrick // There is only one variant this argument could be; put it into the 882061da546Spatrick // argument entry. 883061da546Spatrick arg2.push_back(index_arg); 884061da546Spatrick 885061da546Spatrick // Define the first (and only) variant of this arg. 886061da546Spatrick value_arg.arg_type = eArgTypeValue; 887061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain; 888061da546Spatrick 889061da546Spatrick // There is only one variant this argument could be; put it into the 890061da546Spatrick // argument entry. 891061da546Spatrick arg3.push_back(value_arg); 892061da546Spatrick 893061da546Spatrick // Push the data for the first argument into the m_arguments vector. 894061da546Spatrick m_arguments.push_back(arg1); 895061da546Spatrick m_arguments.push_back(arg2); 896061da546Spatrick m_arguments.push_back(arg3); 897061da546Spatrick } 898061da546Spatrick 899061da546Spatrick ~CommandObjectSettingsInsertAfter() override = default; 900061da546Spatrick 901061da546Spatrick // Overrides base class's behavior where WantsCompletion = 902061da546Spatrick // !WantsRawCommandString. 903061da546Spatrick bool WantsCompletion() override { return true; } 904061da546Spatrick 905061da546Spatrick void 906061da546Spatrick HandleArgumentCompletion(CompletionRequest &request, 907061da546Spatrick OptionElementVector &opt_element_vector) override { 908061da546Spatrick // Attempting to complete variable name 909061da546Spatrick if (request.GetCursorIndex() < 2) 910061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks( 911061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, 912061da546Spatrick request, nullptr); 913061da546Spatrick } 914061da546Spatrick 915061da546Spatrick protected: 916061da546Spatrick bool DoExecute(llvm::StringRef command, 917061da546Spatrick CommandReturnObject &result) override { 918061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult); 919061da546Spatrick 920061da546Spatrick Args cmd_args(command); 921061da546Spatrick const size_t argc = cmd_args.GetArgumentCount(); 922061da546Spatrick 923061da546Spatrick if (argc < 3) { 924061da546Spatrick result.AppendError("'settings insert-after' takes more arguments"); 925061da546Spatrick result.SetStatus(eReturnStatusFailed); 926061da546Spatrick return false; 927061da546Spatrick } 928061da546Spatrick 929061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0); 930061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) { 931061da546Spatrick result.AppendError("'settings insert-after' command requires a valid " 932061da546Spatrick "variable name; No value supplied"); 933061da546Spatrick result.SetStatus(eReturnStatusFailed); 934061da546Spatrick return false; 935061da546Spatrick } 936061da546Spatrick 937061da546Spatrick // Split the raw command into var_name, index_value, and value triple. 938061da546Spatrick llvm::StringRef var_value(command); 939061da546Spatrick var_value = var_value.split(var_name).second.trim(); 940061da546Spatrick 941061da546Spatrick Status error(GetDebugger().SetPropertyValue( 942061da546Spatrick &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value)); 943061da546Spatrick if (error.Fail()) { 944061da546Spatrick result.AppendError(error.AsCString()); 945061da546Spatrick result.SetStatus(eReturnStatusFailed); 946061da546Spatrick return false; 947061da546Spatrick } 948061da546Spatrick 949061da546Spatrick return result.Succeeded(); 950061da546Spatrick } 951061da546Spatrick }; 952061da546Spatrick 953061da546Spatrick // CommandObjectSettingsAppend 954061da546Spatrick 955061da546Spatrick class CommandObjectSettingsAppend : public CommandObjectRaw { 956061da546Spatrick public: 957061da546Spatrick CommandObjectSettingsAppend(CommandInterpreter &interpreter) 958061da546Spatrick : CommandObjectRaw(interpreter, "settings append", 959061da546Spatrick "Append one or more values to a debugger array, " 960061da546Spatrick "dictionary, or string setting.") { 961061da546Spatrick CommandArgumentEntry arg1; 962061da546Spatrick CommandArgumentEntry arg2; 963061da546Spatrick CommandArgumentData var_name_arg; 964061da546Spatrick CommandArgumentData value_arg; 965061da546Spatrick 966061da546Spatrick // Define the first (and only) variant of this arg. 967061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 968061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain; 969061da546Spatrick 970061da546Spatrick // There is only one variant this argument could be; put it into the 971061da546Spatrick // argument entry. 972061da546Spatrick arg1.push_back(var_name_arg); 973061da546Spatrick 974061da546Spatrick // Define the first (and only) variant of this arg. 975061da546Spatrick value_arg.arg_type = eArgTypeValue; 976061da546Spatrick value_arg.arg_repetition = eArgRepeatPlain; 977061da546Spatrick 978061da546Spatrick // There is only one variant this argument could be; put it into the 979061da546Spatrick // argument entry. 980061da546Spatrick arg2.push_back(value_arg); 981061da546Spatrick 982061da546Spatrick // Push the data for the first argument into the m_arguments vector. 983061da546Spatrick m_arguments.push_back(arg1); 984061da546Spatrick m_arguments.push_back(arg2); 985061da546Spatrick } 986061da546Spatrick 987061da546Spatrick ~CommandObjectSettingsAppend() override = default; 988061da546Spatrick 989061da546Spatrick // Overrides base class's behavior where WantsCompletion = 990061da546Spatrick // !WantsRawCommandString. 991061da546Spatrick bool WantsCompletion() override { return true; } 992061da546Spatrick 993061da546Spatrick void 994061da546Spatrick HandleArgumentCompletion(CompletionRequest &request, 995061da546Spatrick OptionElementVector &opt_element_vector) override { 996061da546Spatrick // Attempting to complete variable name 997061da546Spatrick if (request.GetCursorIndex() < 2) 998061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks( 999061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, 1000061da546Spatrick request, nullptr); 1001061da546Spatrick } 1002061da546Spatrick 1003061da546Spatrick protected: 1004061da546Spatrick bool DoExecute(llvm::StringRef command, 1005061da546Spatrick CommandReturnObject &result) override { 1006061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult); 1007061da546Spatrick Args cmd_args(command); 1008061da546Spatrick const size_t argc = cmd_args.GetArgumentCount(); 1009061da546Spatrick 1010061da546Spatrick if (argc < 2) { 1011061da546Spatrick result.AppendError("'settings append' takes more arguments"); 1012061da546Spatrick result.SetStatus(eReturnStatusFailed); 1013061da546Spatrick return false; 1014061da546Spatrick } 1015061da546Spatrick 1016061da546Spatrick const char *var_name = cmd_args.GetArgumentAtIndex(0); 1017061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) { 1018061da546Spatrick result.AppendError("'settings append' command requires a valid variable " 1019061da546Spatrick "name; No value supplied"); 1020061da546Spatrick result.SetStatus(eReturnStatusFailed); 1021061da546Spatrick return false; 1022061da546Spatrick } 1023061da546Spatrick 1024061da546Spatrick // Do not perform cmd_args.Shift() since StringRef is manipulating the raw 1025061da546Spatrick // character string later on. 1026061da546Spatrick 1027061da546Spatrick // Split the raw command into var_name and value pair. 1028061da546Spatrick llvm::StringRef var_value(command); 1029061da546Spatrick var_value = var_value.split(var_name).second.trim(); 1030061da546Spatrick 1031061da546Spatrick Status error(GetDebugger().SetPropertyValue( 1032061da546Spatrick &m_exe_ctx, eVarSetOperationAppend, var_name, var_value)); 1033061da546Spatrick if (error.Fail()) { 1034061da546Spatrick result.AppendError(error.AsCString()); 1035061da546Spatrick result.SetStatus(eReturnStatusFailed); 1036061da546Spatrick return false; 1037061da546Spatrick } 1038061da546Spatrick 1039061da546Spatrick return result.Succeeded(); 1040061da546Spatrick } 1041061da546Spatrick }; 1042061da546Spatrick 1043061da546Spatrick // CommandObjectSettingsClear 1044*dda28197Spatrick #define LLDB_OPTIONS_settings_clear 1045*dda28197Spatrick #include "CommandOptions.inc" 1046061da546Spatrick 1047061da546Spatrick class CommandObjectSettingsClear : public CommandObjectParsed { 1048061da546Spatrick public: 1049061da546Spatrick CommandObjectSettingsClear(CommandInterpreter &interpreter) 1050061da546Spatrick : CommandObjectParsed( 1051061da546Spatrick interpreter, "settings clear", 1052*dda28197Spatrick "Clear a debugger setting array, dictionary, or string. " 1053*dda28197Spatrick "If '-a' option is specified, it clears all settings.", nullptr) { 1054061da546Spatrick CommandArgumentEntry arg; 1055061da546Spatrick CommandArgumentData var_name_arg; 1056061da546Spatrick 1057061da546Spatrick // Define the first (and only) variant of this arg. 1058061da546Spatrick var_name_arg.arg_type = eArgTypeSettingVariableName; 1059061da546Spatrick var_name_arg.arg_repetition = eArgRepeatPlain; 1060061da546Spatrick 1061061da546Spatrick // There is only one variant this argument could be; put it into the 1062061da546Spatrick // argument entry. 1063061da546Spatrick arg.push_back(var_name_arg); 1064061da546Spatrick 1065061da546Spatrick // Push the data for the first argument into the m_arguments vector. 1066061da546Spatrick m_arguments.push_back(arg); 1067061da546Spatrick } 1068061da546Spatrick 1069061da546Spatrick ~CommandObjectSettingsClear() override = default; 1070061da546Spatrick 1071061da546Spatrick void 1072061da546Spatrick HandleArgumentCompletion(CompletionRequest &request, 1073061da546Spatrick OptionElementVector &opt_element_vector) override { 1074061da546Spatrick // Attempting to complete variable name 1075061da546Spatrick if (request.GetCursorIndex() < 2) 1076061da546Spatrick CommandCompletions::InvokeCommonCompletionCallbacks( 1077061da546Spatrick GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, 1078061da546Spatrick request, nullptr); 1079061da546Spatrick } 1080061da546Spatrick 1081*dda28197Spatrick Options *GetOptions() override { return &m_options; } 1082*dda28197Spatrick 1083*dda28197Spatrick class CommandOptions : public Options { 1084*dda28197Spatrick public: 1085*dda28197Spatrick CommandOptions() = default; 1086*dda28197Spatrick 1087*dda28197Spatrick ~CommandOptions() override = default; 1088*dda28197Spatrick 1089*dda28197Spatrick Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1090*dda28197Spatrick ExecutionContext *execution_context) override { 1091*dda28197Spatrick const int short_option = m_getopt_table[option_idx].val; 1092*dda28197Spatrick switch (short_option) { 1093*dda28197Spatrick case 'a': 1094*dda28197Spatrick m_clear_all = true; 1095*dda28197Spatrick break; 1096*dda28197Spatrick default: 1097*dda28197Spatrick llvm_unreachable("Unimplemented option"); 1098*dda28197Spatrick } 1099*dda28197Spatrick return Status(); 1100*dda28197Spatrick } 1101*dda28197Spatrick 1102*dda28197Spatrick void OptionParsingStarting(ExecutionContext *execution_context) override { 1103*dda28197Spatrick m_clear_all = false; 1104*dda28197Spatrick } 1105*dda28197Spatrick 1106*dda28197Spatrick llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1107*dda28197Spatrick return llvm::makeArrayRef(g_settings_clear_options); 1108*dda28197Spatrick } 1109*dda28197Spatrick 1110*dda28197Spatrick bool m_clear_all = false; 1111*dda28197Spatrick }; 1112*dda28197Spatrick 1113061da546Spatrick protected: 1114061da546Spatrick bool DoExecute(Args &command, CommandReturnObject &result) override { 1115061da546Spatrick result.SetStatus(eReturnStatusSuccessFinishNoResult); 1116061da546Spatrick const size_t argc = command.GetArgumentCount(); 1117061da546Spatrick 1118*dda28197Spatrick if (m_options.m_clear_all) { 1119*dda28197Spatrick if (argc != 0) { 1120*dda28197Spatrick result.AppendError("'settings clear --all' doesn't take any arguments"); 1121*dda28197Spatrick result.SetStatus(eReturnStatusFailed); 1122*dda28197Spatrick return false; 1123*dda28197Spatrick } 1124*dda28197Spatrick GetDebugger().GetValueProperties()->Clear(); 1125*dda28197Spatrick return result.Succeeded(); 1126*dda28197Spatrick } 1127*dda28197Spatrick 1128061da546Spatrick if (argc != 1) { 1129061da546Spatrick result.AppendError("'settings clear' takes exactly one argument"); 1130061da546Spatrick result.SetStatus(eReturnStatusFailed); 1131061da546Spatrick return false; 1132061da546Spatrick } 1133061da546Spatrick 1134061da546Spatrick const char *var_name = command.GetArgumentAtIndex(0); 1135061da546Spatrick if ((var_name == nullptr) || (var_name[0] == '\0')) { 1136061da546Spatrick result.AppendError("'settings clear' command requires a valid variable " 1137061da546Spatrick "name; No value supplied"); 1138061da546Spatrick result.SetStatus(eReturnStatusFailed); 1139061da546Spatrick return false; 1140061da546Spatrick } 1141061da546Spatrick 1142061da546Spatrick Status error(GetDebugger().SetPropertyValue( 1143061da546Spatrick &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef())); 1144061da546Spatrick if (error.Fail()) { 1145061da546Spatrick result.AppendError(error.AsCString()); 1146061da546Spatrick result.SetStatus(eReturnStatusFailed); 1147061da546Spatrick return false; 1148061da546Spatrick } 1149061da546Spatrick 1150061da546Spatrick return result.Succeeded(); 1151061da546Spatrick } 1152*dda28197Spatrick 1153*dda28197Spatrick private: 1154*dda28197Spatrick CommandOptions m_options; 1155061da546Spatrick }; 1156061da546Spatrick 1157061da546Spatrick // CommandObjectMultiwordSettings 1158061da546Spatrick 1159061da546Spatrick CommandObjectMultiwordSettings::CommandObjectMultiwordSettings( 1160061da546Spatrick CommandInterpreter &interpreter) 1161061da546Spatrick : CommandObjectMultiword(interpreter, "settings", 1162061da546Spatrick "Commands for managing LLDB settings.", 1163061da546Spatrick "settings <subcommand> [<command-options>]") { 1164061da546Spatrick LoadSubCommand("set", 1165061da546Spatrick CommandObjectSP(new CommandObjectSettingsSet(interpreter))); 1166061da546Spatrick LoadSubCommand("show", 1167061da546Spatrick CommandObjectSP(new CommandObjectSettingsShow(interpreter))); 1168061da546Spatrick LoadSubCommand("list", 1169061da546Spatrick CommandObjectSP(new CommandObjectSettingsList(interpreter))); 1170061da546Spatrick LoadSubCommand("remove", 1171061da546Spatrick CommandObjectSP(new CommandObjectSettingsRemove(interpreter))); 1172061da546Spatrick LoadSubCommand("replace", CommandObjectSP( 1173061da546Spatrick new CommandObjectSettingsReplace(interpreter))); 1174061da546Spatrick LoadSubCommand( 1175061da546Spatrick "insert-before", 1176061da546Spatrick CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter))); 1177061da546Spatrick LoadSubCommand( 1178061da546Spatrick "insert-after", 1179061da546Spatrick CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter))); 1180061da546Spatrick LoadSubCommand("append", 1181061da546Spatrick CommandObjectSP(new CommandObjectSettingsAppend(interpreter))); 1182061da546Spatrick LoadSubCommand("clear", 1183061da546Spatrick CommandObjectSP(new CommandObjectSettingsClear(interpreter))); 1184061da546Spatrick LoadSubCommand("write", 1185061da546Spatrick CommandObjectSP(new CommandObjectSettingsWrite(interpreter))); 1186061da546Spatrick LoadSubCommand("read", 1187061da546Spatrick CommandObjectSP(new CommandObjectSettingsRead(interpreter))); 1188061da546Spatrick } 1189061da546Spatrick 1190061da546Spatrick CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default; 1191