1ac7ddfbfSEd Maste //===-- CommandObjectSettings.cpp -------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "CommandObjectSettings.h"
11ac7ddfbfSEd Maste 
124bb0738eSEd Maste #include "llvm/ADT/StringRef.h"
134bb0738eSEd Maste 
14f678e45dSDimitry Andric #include "lldb/Host/OptionParser.h"
15435933ddSDimitry Andric #include "lldb/Interpreter/CommandCompletions.h"
16ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
17ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
181c3bbb01SEd Maste #include "lldb/Interpreter/OptionValueProperties.h"
19ac7ddfbfSEd Maste 
20ac7ddfbfSEd Maste using namespace lldb;
21ac7ddfbfSEd Maste using namespace lldb_private;
22ac7ddfbfSEd Maste 
23ac7ddfbfSEd Maste //-------------------------------------------------------------------------
24ac7ddfbfSEd Maste // CommandObjectSettingsSet
25ac7ddfbfSEd Maste //-------------------------------------------------------------------------
26ac7ddfbfSEd Maste 
27*b5893f02SDimitry Andric static constexpr OptionDefinition g_settings_set_options[] = {
28435933ddSDimitry Andric     // clang-format off
29*b5893f02SDimitry Andric   { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Apply the new value to the global default value." },
30*b5893f02SDimitry Andric   { LLDB_OPT_SET_2, false, "force",  'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Force an empty value to be accepted as the default." }
31435933ddSDimitry Andric     // clang-format on
32435933ddSDimitry Andric };
33435933ddSDimitry Andric 
34435933ddSDimitry Andric class CommandObjectSettingsSet : public CommandObjectRaw {
35ac7ddfbfSEd Maste public:
CommandObjectSettingsSet(CommandInterpreter & interpreter)364bb0738eSEd Maste   CommandObjectSettingsSet(CommandInterpreter &interpreter)
37435933ddSDimitry Andric       : CommandObjectRaw(interpreter, "settings set",
38435933ddSDimitry Andric                          "Set the value of the specified debugger setting."),
39435933ddSDimitry Andric         m_options() {
40ac7ddfbfSEd Maste     CommandArgumentEntry arg1;
41ac7ddfbfSEd Maste     CommandArgumentEntry arg2;
42ac7ddfbfSEd Maste     CommandArgumentData var_name_arg;
43ac7ddfbfSEd Maste     CommandArgumentData value_arg;
44ac7ddfbfSEd Maste 
45ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
46ac7ddfbfSEd Maste     var_name_arg.arg_type = eArgTypeSettingVariableName;
47ac7ddfbfSEd Maste     var_name_arg.arg_repetition = eArgRepeatPlain;
48ac7ddfbfSEd Maste 
49435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
50435933ddSDimitry Andric     // argument entry.
51ac7ddfbfSEd Maste     arg1.push_back(var_name_arg);
52ac7ddfbfSEd Maste 
53ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
54ac7ddfbfSEd Maste     value_arg.arg_type = eArgTypeValue;
55ac7ddfbfSEd Maste     value_arg.arg_repetition = eArgRepeatPlain;
56ac7ddfbfSEd Maste 
57435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
58435933ddSDimitry Andric     // argument entry.
59ac7ddfbfSEd Maste     arg2.push_back(value_arg);
60ac7ddfbfSEd Maste 
61ac7ddfbfSEd Maste     // Push the data for the first argument into the m_arguments vector.
62ac7ddfbfSEd Maste     m_arguments.push_back(arg1);
63ac7ddfbfSEd Maste     m_arguments.push_back(arg2);
64ac7ddfbfSEd Maste 
65ac7ddfbfSEd Maste     SetHelpLong(
66b91a7dfcSDimitry Andric         "\nWhen setting a dictionary or array variable, you can set multiple entries \
67435933ddSDimitry Andric at once by giving the values to the set command.  For example:"
68435933ddSDimitry Andric         R"(
69b91a7dfcSDimitry Andric 
70b91a7dfcSDimitry Andric (lldb) settings set target.run-args value1 value2 value3
71b91a7dfcSDimitry Andric (lldb) settings set target.env-vars MYPATH=~/.:/usr/bin  SOME_ENV_VAR=12345
72b91a7dfcSDimitry Andric 
73b91a7dfcSDimitry Andric (lldb) settings show target.run-args
74b91a7dfcSDimitry Andric   [0]: 'value1'
75b91a7dfcSDimitry Andric   [1]: 'value2'
76b91a7dfcSDimitry Andric   [3]: 'value3'
77b91a7dfcSDimitry Andric (lldb) settings show target.env-vars
78b91a7dfcSDimitry Andric   'MYPATH=~/.:/usr/bin'
79b91a7dfcSDimitry Andric   'SOME_ENV_VAR=12345'
80b91a7dfcSDimitry Andric 
81435933ddSDimitry Andric )"
82435933ddSDimitry Andric         "Warning:  The 'set' command re-sets the entire array or dictionary.  If you \
83b91a7dfcSDimitry Andric just want to add, remove or update individual values (or add something to \
84b91a7dfcSDimitry Andric the end), use one of the other settings sub-commands: append, replace, \
85435933ddSDimitry Andric insert-before or insert-after.");
86ac7ddfbfSEd Maste   }
87ac7ddfbfSEd Maste 
884bb0738eSEd Maste   ~CommandObjectSettingsSet() override = default;
89ac7ddfbfSEd Maste 
90435933ddSDimitry Andric   // Overrides base class's behavior where WantsCompletion =
91435933ddSDimitry Andric   // !WantsRawCommandString.
WantsCompletion()92435933ddSDimitry Andric   bool WantsCompletion() override { return true; }
93ac7ddfbfSEd Maste 
GetOptions()94435933ddSDimitry Andric   Options *GetOptions() override { return &m_options; }
95ac7ddfbfSEd Maste 
96435933ddSDimitry Andric   class CommandOptions : public Options {
97ac7ddfbfSEd Maste   public:
CommandOptions()98435933ddSDimitry Andric     CommandOptions() : Options(), m_global(false) {}
99ac7ddfbfSEd Maste 
1004bb0738eSEd Maste     ~CommandOptions() override = default;
101ac7ddfbfSEd Maste 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)1025517e702SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
103435933ddSDimitry Andric                           ExecutionContext *execution_context) override {
1045517e702SDimitry Andric       Status error;
105ac7ddfbfSEd Maste       const int short_option = m_getopt_table[option_idx].val;
106ac7ddfbfSEd Maste 
107435933ddSDimitry Andric       switch (short_option) {
108*b5893f02SDimitry Andric       case 'f':
109*b5893f02SDimitry Andric         m_force = true;
110*b5893f02SDimitry Andric         break;
111ac7ddfbfSEd Maste       case 'g':
112ac7ddfbfSEd Maste         m_global = true;
113ac7ddfbfSEd Maste         break;
114ac7ddfbfSEd Maste       default:
115435933ddSDimitry Andric         error.SetErrorStringWithFormat("unrecognized options '%c'",
116435933ddSDimitry Andric                                        short_option);
117ac7ddfbfSEd Maste         break;
118ac7ddfbfSEd Maste       }
119ac7ddfbfSEd Maste 
120ac7ddfbfSEd Maste       return error;
121ac7ddfbfSEd Maste     }
122ac7ddfbfSEd Maste 
OptionParsingStarting(ExecutionContext * execution_context)123435933ddSDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
124ac7ddfbfSEd Maste       m_global = false;
125*b5893f02SDimitry Andric       m_force = false;
126ac7ddfbfSEd Maste     }
127ac7ddfbfSEd Maste 
GetDefinitions()128435933ddSDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
129435933ddSDimitry Andric       return llvm::makeArrayRef(g_settings_set_options);
130ac7ddfbfSEd Maste     }
131ac7ddfbfSEd Maste 
132ac7ddfbfSEd Maste     // Instance variables to hold the values for command options.
133ac7ddfbfSEd Maste     bool m_global;
134*b5893f02SDimitry Andric     bool m_force;
135ac7ddfbfSEd Maste   };
136ac7ddfbfSEd Maste 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1374ba319b5SDimitry Andric   int HandleArgumentCompletion(
1384ba319b5SDimitry Andric       CompletionRequest &request,
1394ba319b5SDimitry Andric       OptionElementVector &opt_element_vector) override {
140ac7ddfbfSEd Maste 
1414ba319b5SDimitry Andric     const size_t argc = request.GetParsedLine().GetArgumentCount();
1424bb0738eSEd Maste     const char *arg = nullptr;
143ac7ddfbfSEd Maste     int setting_var_idx;
1444ba319b5SDimitry Andric     for (setting_var_idx = 0; setting_var_idx < static_cast<int>(argc);
145435933ddSDimitry Andric          ++setting_var_idx) {
1464ba319b5SDimitry Andric       arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
147ac7ddfbfSEd Maste       if (arg && arg[0] != '-')
148ac7ddfbfSEd Maste         break; // We found our setting variable name index
149ac7ddfbfSEd Maste     }
1504ba319b5SDimitry Andric     if (request.GetCursorIndex() == setting_var_idx) {
151ac7ddfbfSEd Maste       // Attempting to complete setting variable name
152435933ddSDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
153435933ddSDimitry Andric           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
1544ba319b5SDimitry Andric           request, nullptr);
155435933ddSDimitry Andric     } else {
1564ba319b5SDimitry Andric       arg =
1574ba319b5SDimitry Andric           request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
158ac7ddfbfSEd Maste 
159435933ddSDimitry Andric       if (arg) {
160435933ddSDimitry Andric         if (arg[0] == '-') {
161ac7ddfbfSEd Maste           // Complete option name
162435933ddSDimitry Andric         } else {
163ac7ddfbfSEd Maste           // Complete setting value
164435933ddSDimitry Andric           const char *setting_var_name =
1654ba319b5SDimitry Andric               request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
1665517e702SDimitry Andric           Status error;
167435933ddSDimitry Andric           lldb::OptionValueSP value_sp(
168435933ddSDimitry Andric               m_interpreter.GetDebugger().GetPropertyValue(
169435933ddSDimitry Andric                   &m_exe_ctx, setting_var_name, false, error));
170435933ddSDimitry Andric           if (value_sp) {
1714ba319b5SDimitry Andric             value_sp->AutoComplete(m_interpreter, request);
172ac7ddfbfSEd Maste           }
173ac7ddfbfSEd Maste         }
174ac7ddfbfSEd Maste       }
175ac7ddfbfSEd Maste     }
1764ba319b5SDimitry Andric     return request.GetNumberOfMatches();
177ac7ddfbfSEd Maste   }
178ac7ddfbfSEd Maste 
179ac7ddfbfSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)1804ba319b5SDimitry Andric   bool DoExecute(llvm::StringRef command,
1814ba319b5SDimitry Andric                  CommandReturnObject &result) override {
182ac7ddfbfSEd Maste     Args cmd_args(command);
183ac7ddfbfSEd Maste 
184ac7ddfbfSEd Maste     // Process possible options.
185ac7ddfbfSEd Maste     if (!ParseOptions(cmd_args, result))
186ac7ddfbfSEd Maste       return false;
187ac7ddfbfSEd Maste 
188*b5893f02SDimitry Andric     const size_t min_argc = m_options.m_force ? 1 : 2;
189ac7ddfbfSEd Maste     const size_t argc = cmd_args.GetArgumentCount();
190*b5893f02SDimitry Andric 
191*b5893f02SDimitry Andric     if ((argc < min_argc) && (!m_options.m_global)) {
192ac7ddfbfSEd Maste       result.AppendError("'settings set' takes more arguments");
193ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
194ac7ddfbfSEd Maste       return false;
195ac7ddfbfSEd Maste     }
196ac7ddfbfSEd Maste 
197ac7ddfbfSEd Maste     const char *var_name = cmd_args.GetArgumentAtIndex(0);
198435933ddSDimitry Andric     if ((var_name == nullptr) || (var_name[0] == '\0')) {
199435933ddSDimitry Andric       result.AppendError(
200435933ddSDimitry Andric           "'settings set' command requires a valid variable name");
201ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
202ac7ddfbfSEd Maste       return false;
203ac7ddfbfSEd Maste     }
204ac7ddfbfSEd Maste 
205*b5893f02SDimitry Andric     // A missing value corresponds to clearing the setting when "force" is
206*b5893f02SDimitry Andric     // specified.
207*b5893f02SDimitry Andric     if (argc == 1 && m_options.m_force) {
208*b5893f02SDimitry Andric       Status error(m_interpreter.GetDebugger().SetPropertyValue(
209*b5893f02SDimitry Andric           &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
210*b5893f02SDimitry Andric       if (error.Fail()) {
211*b5893f02SDimitry Andric         result.AppendError(error.AsCString());
212*b5893f02SDimitry Andric         result.SetStatus(eReturnStatusFailed);
213*b5893f02SDimitry Andric         return false;
214*b5893f02SDimitry Andric       }
215*b5893f02SDimitry Andric       return result.Succeeded();
216*b5893f02SDimitry Andric     }
217*b5893f02SDimitry Andric 
218ac7ddfbfSEd Maste     // Split the raw command into var_name and value pair.
219ac7ddfbfSEd Maste     llvm::StringRef raw_str(command);
220ac7ddfbfSEd Maste     std::string var_value_string = raw_str.split(var_name).second.str();
221435933ddSDimitry Andric     const char *var_value_cstr =
222435933ddSDimitry Andric         Args::StripSpaces(var_value_string, true, false, false);
223ac7ddfbfSEd Maste 
2245517e702SDimitry Andric     Status error;
225435933ddSDimitry Andric     if (m_options.m_global) {
226435933ddSDimitry Andric       error = m_interpreter.GetDebugger().SetPropertyValue(
227435933ddSDimitry Andric           nullptr, eVarSetOperationAssign, var_name, var_value_cstr);
228ac7ddfbfSEd Maste     }
229ac7ddfbfSEd Maste 
230435933ddSDimitry Andric     if (error.Success()) {
231ac7ddfbfSEd Maste       // FIXME this is the same issue as the one in commands script import
232435933ddSDimitry Andric       // we could be setting target.load-script-from-symbol-file which would
2334ba319b5SDimitry Andric       // cause Python scripts to be loaded, which could run LLDB commands (e.g.
2344ba319b5SDimitry Andric       // settings set target.process.python-os-plugin-path) and cause a crash
235ac7ddfbfSEd Maste       // if we did not clear the command's exe_ctx first
236ac7ddfbfSEd Maste       ExecutionContext exe_ctx(m_exe_ctx);
237ac7ddfbfSEd Maste       m_exe_ctx.Clear();
238435933ddSDimitry Andric       error = m_interpreter.GetDebugger().SetPropertyValue(
239435933ddSDimitry Andric           &exe_ctx, eVarSetOperationAssign, var_name, var_value_cstr);
240ac7ddfbfSEd Maste     }
241ac7ddfbfSEd Maste 
242435933ddSDimitry Andric     if (error.Fail()) {
243ac7ddfbfSEd Maste       result.AppendError(error.AsCString());
244ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
245ac7ddfbfSEd Maste       return false;
246435933ddSDimitry Andric     } else {
247ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusSuccessFinishResult);
248ac7ddfbfSEd Maste     }
249ac7ddfbfSEd Maste 
250ac7ddfbfSEd Maste     return result.Succeeded();
251ac7ddfbfSEd Maste   }
2524bb0738eSEd Maste 
253ac7ddfbfSEd Maste private:
254ac7ddfbfSEd Maste   CommandOptions m_options;
255ac7ddfbfSEd Maste };
256ac7ddfbfSEd Maste 
257ac7ddfbfSEd Maste //-------------------------------------------------------------------------
258ac7ddfbfSEd Maste // CommandObjectSettingsShow -- Show current values
259ac7ddfbfSEd Maste //-------------------------------------------------------------------------
260ac7ddfbfSEd Maste 
261435933ddSDimitry Andric class CommandObjectSettingsShow : public CommandObjectParsed {
262ac7ddfbfSEd Maste public:
CommandObjectSettingsShow(CommandInterpreter & interpreter)2634bb0738eSEd Maste   CommandObjectSettingsShow(CommandInterpreter &interpreter)
264435933ddSDimitry Andric       : CommandObjectParsed(interpreter, "settings show",
265435933ddSDimitry Andric                             "Show matching debugger settings and their current "
266435933ddSDimitry Andric                             "values.  Defaults to showing all settings.",
267435933ddSDimitry Andric                             nullptr) {
268ac7ddfbfSEd Maste     CommandArgumentEntry arg1;
269ac7ddfbfSEd Maste     CommandArgumentData var_name_arg;
270ac7ddfbfSEd Maste 
271ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
272ac7ddfbfSEd Maste     var_name_arg.arg_type = eArgTypeSettingVariableName;
273ac7ddfbfSEd Maste     var_name_arg.arg_repetition = eArgRepeatOptional;
274ac7ddfbfSEd Maste 
275435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
276435933ddSDimitry Andric     // argument entry.
277ac7ddfbfSEd Maste     arg1.push_back(var_name_arg);
278ac7ddfbfSEd Maste 
279ac7ddfbfSEd Maste     // Push the data for the first argument into the m_arguments vector.
280ac7ddfbfSEd Maste     m_arguments.push_back(arg1);
281ac7ddfbfSEd Maste   }
282ac7ddfbfSEd Maste 
2834bb0738eSEd Maste   ~CommandObjectSettingsShow() override = default;
284ac7ddfbfSEd Maste 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)2854ba319b5SDimitry Andric   int HandleArgumentCompletion(
2864ba319b5SDimitry Andric       CompletionRequest &request,
2874ba319b5SDimitry Andric       OptionElementVector &opt_element_vector) override {
288435933ddSDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
289435933ddSDimitry Andric         GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
2904ba319b5SDimitry Andric         request, nullptr);
2914ba319b5SDimitry Andric     return request.GetNumberOfMatches();
292ac7ddfbfSEd Maste   }
293ac7ddfbfSEd Maste 
294ac7ddfbfSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)295435933ddSDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
296ac7ddfbfSEd Maste     result.SetStatus(eReturnStatusSuccessFinishResult);
297ac7ddfbfSEd Maste 
298435933ddSDimitry Andric     if (!args.empty()) {
299435933ddSDimitry Andric       for (const auto &arg : args) {
3005517e702SDimitry Andric         Status error(m_interpreter.GetDebugger().DumpPropertyValue(
301435933ddSDimitry Andric             &m_exe_ctx, result.GetOutputStream(), arg.ref,
302435933ddSDimitry Andric             OptionValue::eDumpGroupValue));
303435933ddSDimitry Andric         if (error.Success()) {
304ac7ddfbfSEd Maste           result.GetOutputStream().EOL();
305435933ddSDimitry Andric         } else {
306ac7ddfbfSEd Maste           result.AppendError(error.AsCString());
307ac7ddfbfSEd Maste           result.SetStatus(eReturnStatusFailed);
308ac7ddfbfSEd Maste         }
309ac7ddfbfSEd Maste       }
310435933ddSDimitry Andric     } else {
311435933ddSDimitry Andric       m_interpreter.GetDebugger().DumpAllPropertyValues(
312435933ddSDimitry Andric           &m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue);
313ac7ddfbfSEd Maste     }
314ac7ddfbfSEd Maste 
315ac7ddfbfSEd Maste     return result.Succeeded();
316ac7ddfbfSEd Maste   }
317ac7ddfbfSEd Maste };
318ac7ddfbfSEd Maste 
319ac7ddfbfSEd Maste //-------------------------------------------------------------------------
320*b5893f02SDimitry Andric // CommandObjectSettingsWrite -- Write settings to file
321*b5893f02SDimitry Andric //-------------------------------------------------------------------------
322*b5893f02SDimitry Andric 
323*b5893f02SDimitry Andric static constexpr OptionDefinition g_settings_write_options[] = {
324*b5893f02SDimitry Andric     // clang-format off
325*b5893f02SDimitry Andric   { LLDB_OPT_SET_ALL, true,  "file",  'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename,    "The file into which to write the settings." },
326*b5893f02SDimitry Andric   { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument,       nullptr, {}, 0,                                       eArgTypeNone,        "Append to saved settings file if it exists."},
327*b5893f02SDimitry Andric     // clang-format on
328*b5893f02SDimitry Andric };
329*b5893f02SDimitry Andric 
330*b5893f02SDimitry Andric class CommandObjectSettingsWrite : public CommandObjectParsed {
331*b5893f02SDimitry Andric public:
CommandObjectSettingsWrite(CommandInterpreter & interpreter)332*b5893f02SDimitry Andric   CommandObjectSettingsWrite(CommandInterpreter &interpreter)
333*b5893f02SDimitry Andric       : CommandObjectParsed(
334*b5893f02SDimitry Andric             interpreter, "settings export",
335*b5893f02SDimitry Andric             "Write matching debugger settings and their "
336*b5893f02SDimitry Andric             "current values to a file that can be read in with "
337*b5893f02SDimitry Andric             "\"settings read\". Defaults to writing all settings.",
338*b5893f02SDimitry Andric             nullptr),
339*b5893f02SDimitry Andric         m_options() {
340*b5893f02SDimitry Andric     CommandArgumentEntry arg1;
341*b5893f02SDimitry Andric     CommandArgumentData var_name_arg;
342*b5893f02SDimitry Andric 
343*b5893f02SDimitry Andric     // Define the first (and only) variant of this arg.
344*b5893f02SDimitry Andric     var_name_arg.arg_type = eArgTypeSettingVariableName;
345*b5893f02SDimitry Andric     var_name_arg.arg_repetition = eArgRepeatOptional;
346*b5893f02SDimitry Andric 
347*b5893f02SDimitry Andric     // There is only one variant this argument could be; put it into the
348*b5893f02SDimitry Andric     // argument entry.
349*b5893f02SDimitry Andric     arg1.push_back(var_name_arg);
350*b5893f02SDimitry Andric 
351*b5893f02SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
352*b5893f02SDimitry Andric     m_arguments.push_back(arg1);
353*b5893f02SDimitry Andric   }
354*b5893f02SDimitry Andric 
355*b5893f02SDimitry Andric   ~CommandObjectSettingsWrite() override = default;
356*b5893f02SDimitry Andric 
GetOptions()357*b5893f02SDimitry Andric   Options *GetOptions() override { return &m_options; }
358*b5893f02SDimitry Andric 
359*b5893f02SDimitry Andric   class CommandOptions : public Options {
360*b5893f02SDimitry Andric   public:
CommandOptions()361*b5893f02SDimitry Andric     CommandOptions() : Options() {}
362*b5893f02SDimitry Andric 
363*b5893f02SDimitry Andric     ~CommandOptions() override = default;
364*b5893f02SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)365*b5893f02SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
366*b5893f02SDimitry Andric                           ExecutionContext *execution_context) override {
367*b5893f02SDimitry Andric       Status error;
368*b5893f02SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
369*b5893f02SDimitry Andric 
370*b5893f02SDimitry Andric       switch (short_option) {
371*b5893f02SDimitry Andric       case 'f':
372*b5893f02SDimitry Andric         m_filename.assign(option_arg);
373*b5893f02SDimitry Andric         break;
374*b5893f02SDimitry Andric       case 'a':
375*b5893f02SDimitry Andric         m_append = true;
376*b5893f02SDimitry Andric         break;
377*b5893f02SDimitry Andric       default:
378*b5893f02SDimitry Andric         error.SetErrorStringWithFormat("unrecognized option '%c'",
379*b5893f02SDimitry Andric                                        short_option);
380*b5893f02SDimitry Andric         break;
381*b5893f02SDimitry Andric       }
382*b5893f02SDimitry Andric 
383*b5893f02SDimitry Andric       return error;
384*b5893f02SDimitry Andric     }
385*b5893f02SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)386*b5893f02SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
387*b5893f02SDimitry Andric       m_filename.clear();
388*b5893f02SDimitry Andric       m_append = false;
389*b5893f02SDimitry Andric     }
390*b5893f02SDimitry Andric 
GetDefinitions()391*b5893f02SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
392*b5893f02SDimitry Andric       return llvm::makeArrayRef(g_settings_write_options);
393*b5893f02SDimitry Andric     }
394*b5893f02SDimitry Andric 
395*b5893f02SDimitry Andric     // Instance variables to hold the values for command options.
396*b5893f02SDimitry Andric     std::string m_filename;
397*b5893f02SDimitry Andric     bool m_append = false;
398*b5893f02SDimitry Andric   };
399*b5893f02SDimitry Andric 
400*b5893f02SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)401*b5893f02SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
402*b5893f02SDimitry Andric     FileSpec file_spec(m_options.m_filename);
403*b5893f02SDimitry Andric     FileSystem::Instance().Resolve(file_spec);
404*b5893f02SDimitry Andric     std::string path(file_spec.GetPath());
405*b5893f02SDimitry Andric     uint32_t options = File::OpenOptions::eOpenOptionWrite |
406*b5893f02SDimitry Andric                        File::OpenOptions::eOpenOptionCanCreate;
407*b5893f02SDimitry Andric     if (m_options.m_append)
408*b5893f02SDimitry Andric       options |= File::OpenOptions::eOpenOptionAppend;
409*b5893f02SDimitry Andric     else
410*b5893f02SDimitry Andric       options |= File::OpenOptions::eOpenOptionTruncate;
411*b5893f02SDimitry Andric 
412*b5893f02SDimitry Andric     StreamFile out_file(path.c_str(), options,
413*b5893f02SDimitry Andric                         lldb::eFilePermissionsFileDefault);
414*b5893f02SDimitry Andric 
415*b5893f02SDimitry Andric     if (!out_file.GetFile().IsValid()) {
416*b5893f02SDimitry Andric       result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
417*b5893f02SDimitry Andric       result.SetStatus(eReturnStatusFailed);
418*b5893f02SDimitry Andric       return false;
419*b5893f02SDimitry Andric     }
420*b5893f02SDimitry Andric 
421*b5893f02SDimitry Andric     // Exporting should not be context sensitive.
422*b5893f02SDimitry Andric     ExecutionContext clean_ctx;
423*b5893f02SDimitry Andric 
424*b5893f02SDimitry Andric     if (args.empty()) {
425*b5893f02SDimitry Andric       m_interpreter.GetDebugger().DumpAllPropertyValues(
426*b5893f02SDimitry Andric           &clean_ctx, out_file, OptionValue::eDumpGroupExport);
427*b5893f02SDimitry Andric       return result.Succeeded();
428*b5893f02SDimitry Andric     }
429*b5893f02SDimitry Andric 
430*b5893f02SDimitry Andric     for (const auto &arg : args) {
431*b5893f02SDimitry Andric       Status error(m_interpreter.GetDebugger().DumpPropertyValue(
432*b5893f02SDimitry Andric           &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport));
433*b5893f02SDimitry Andric       if (!error.Success()) {
434*b5893f02SDimitry Andric         result.AppendError(error.AsCString());
435*b5893f02SDimitry Andric         result.SetStatus(eReturnStatusFailed);
436*b5893f02SDimitry Andric       }
437*b5893f02SDimitry Andric     }
438*b5893f02SDimitry Andric 
439*b5893f02SDimitry Andric     return result.Succeeded();
440*b5893f02SDimitry Andric   }
441*b5893f02SDimitry Andric 
442*b5893f02SDimitry Andric private:
443*b5893f02SDimitry Andric   CommandOptions m_options;
444*b5893f02SDimitry Andric };
445*b5893f02SDimitry Andric 
446*b5893f02SDimitry Andric //-------------------------------------------------------------------------
447*b5893f02SDimitry Andric // CommandObjectSettingsRead -- Read settings from file
448*b5893f02SDimitry Andric //-------------------------------------------------------------------------
449*b5893f02SDimitry Andric 
450*b5893f02SDimitry Andric static constexpr OptionDefinition g_settings_read_options[] = {
451*b5893f02SDimitry Andric     // clang-format off
452*b5893f02SDimitry Andric   {LLDB_OPT_SET_ALL, true, "file",'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename,       "The file from which to read the breakpoints." },
453*b5893f02SDimitry Andric     // clang-format on
454*b5893f02SDimitry Andric };
455*b5893f02SDimitry Andric 
456*b5893f02SDimitry Andric class CommandObjectSettingsRead : public CommandObjectParsed {
457*b5893f02SDimitry Andric public:
CommandObjectSettingsRead(CommandInterpreter & interpreter)458*b5893f02SDimitry Andric   CommandObjectSettingsRead(CommandInterpreter &interpreter)
459*b5893f02SDimitry Andric       : CommandObjectParsed(
460*b5893f02SDimitry Andric             interpreter, "settings read",
461*b5893f02SDimitry Andric             "Read settings previously saved to a file with \"settings write\".",
462*b5893f02SDimitry Andric             nullptr),
463*b5893f02SDimitry Andric         m_options() {}
464*b5893f02SDimitry Andric 
465*b5893f02SDimitry Andric   ~CommandObjectSettingsRead() override = default;
466*b5893f02SDimitry Andric 
GetOptions()467*b5893f02SDimitry Andric   Options *GetOptions() override { return &m_options; }
468*b5893f02SDimitry Andric 
469*b5893f02SDimitry Andric   class CommandOptions : public Options {
470*b5893f02SDimitry Andric   public:
CommandOptions()471*b5893f02SDimitry Andric     CommandOptions() : Options() {}
472*b5893f02SDimitry Andric 
473*b5893f02SDimitry Andric     ~CommandOptions() override = default;
474*b5893f02SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)475*b5893f02SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
476*b5893f02SDimitry Andric                           ExecutionContext *execution_context) override {
477*b5893f02SDimitry Andric       Status error;
478*b5893f02SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
479*b5893f02SDimitry Andric 
480*b5893f02SDimitry Andric       switch (short_option) {
481*b5893f02SDimitry Andric       case 'f':
482*b5893f02SDimitry Andric         m_filename.assign(option_arg);
483*b5893f02SDimitry Andric         break;
484*b5893f02SDimitry Andric       default:
485*b5893f02SDimitry Andric         error.SetErrorStringWithFormat("unrecognized option '%c'",
486*b5893f02SDimitry Andric                                        short_option);
487*b5893f02SDimitry Andric         break;
488*b5893f02SDimitry Andric       }
489*b5893f02SDimitry Andric 
490*b5893f02SDimitry Andric       return error;
491*b5893f02SDimitry Andric     }
492*b5893f02SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)493*b5893f02SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
494*b5893f02SDimitry Andric       m_filename.clear();
495*b5893f02SDimitry Andric     }
496*b5893f02SDimitry Andric 
GetDefinitions()497*b5893f02SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
498*b5893f02SDimitry Andric       return llvm::makeArrayRef(g_settings_read_options);
499*b5893f02SDimitry Andric     }
500*b5893f02SDimitry Andric 
501*b5893f02SDimitry Andric     // Instance variables to hold the values for command options.
502*b5893f02SDimitry Andric     std::string m_filename;
503*b5893f02SDimitry Andric   };
504*b5893f02SDimitry Andric 
505*b5893f02SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)506*b5893f02SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
507*b5893f02SDimitry Andric     FileSpec file(m_options.m_filename);
508*b5893f02SDimitry Andric     FileSystem::Instance().Resolve(file);
509*b5893f02SDimitry Andric     ExecutionContext clean_ctx;
510*b5893f02SDimitry Andric     CommandInterpreterRunOptions options;
511*b5893f02SDimitry Andric     options.SetAddToHistory(false);
512*b5893f02SDimitry Andric     options.SetEchoCommands(false);
513*b5893f02SDimitry Andric     options.SetPrintResults(true);
514*b5893f02SDimitry Andric     options.SetStopOnError(false);
515*b5893f02SDimitry Andric     m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result);
516*b5893f02SDimitry Andric     return result.Succeeded();
517*b5893f02SDimitry Andric   }
518*b5893f02SDimitry Andric 
519*b5893f02SDimitry Andric private:
520*b5893f02SDimitry Andric   CommandOptions m_options;
521*b5893f02SDimitry Andric };
522*b5893f02SDimitry Andric 
523*b5893f02SDimitry Andric //-------------------------------------------------------------------------
524ac7ddfbfSEd Maste // CommandObjectSettingsList -- List settable variables
525ac7ddfbfSEd Maste //-------------------------------------------------------------------------
526ac7ddfbfSEd Maste 
527435933ddSDimitry Andric class CommandObjectSettingsList : public CommandObjectParsed {
528ac7ddfbfSEd Maste public:
CommandObjectSettingsList(CommandInterpreter & interpreter)5294bb0738eSEd Maste   CommandObjectSettingsList(CommandInterpreter &interpreter)
5304bb0738eSEd Maste       : CommandObjectParsed(interpreter, "settings list",
531435933ddSDimitry Andric                             "List and describe matching debugger settings.  "
532435933ddSDimitry Andric                             "Defaults to all listing all settings.",
533435933ddSDimitry Andric                             nullptr) {
534ac7ddfbfSEd Maste     CommandArgumentEntry arg;
535ac7ddfbfSEd Maste     CommandArgumentData var_name_arg;
536ac7ddfbfSEd Maste     CommandArgumentData prefix_name_arg;
537ac7ddfbfSEd Maste 
538ac7ddfbfSEd Maste     // Define the first variant of this arg.
539ac7ddfbfSEd Maste     var_name_arg.arg_type = eArgTypeSettingVariableName;
540ac7ddfbfSEd Maste     var_name_arg.arg_repetition = eArgRepeatOptional;
541ac7ddfbfSEd Maste 
542ac7ddfbfSEd Maste     // Define the second variant of this arg.
543ac7ddfbfSEd Maste     prefix_name_arg.arg_type = eArgTypeSettingPrefix;
544ac7ddfbfSEd Maste     prefix_name_arg.arg_repetition = eArgRepeatOptional;
545ac7ddfbfSEd Maste 
546ac7ddfbfSEd Maste     arg.push_back(var_name_arg);
547ac7ddfbfSEd Maste     arg.push_back(prefix_name_arg);
548ac7ddfbfSEd Maste 
549ac7ddfbfSEd Maste     // Push the data for the first argument into the m_arguments vector.
550ac7ddfbfSEd Maste     m_arguments.push_back(arg);
551ac7ddfbfSEd Maste   }
552ac7ddfbfSEd Maste 
5534bb0738eSEd Maste   ~CommandObjectSettingsList() override = default;
554ac7ddfbfSEd Maste 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)5554ba319b5SDimitry Andric   int HandleArgumentCompletion(
5564ba319b5SDimitry Andric       CompletionRequest &request,
5574ba319b5SDimitry Andric       OptionElementVector &opt_element_vector) override {
558435933ddSDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
559435933ddSDimitry Andric         GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
5604ba319b5SDimitry Andric         request, nullptr);
5614ba319b5SDimitry Andric     return request.GetNumberOfMatches();
562ac7ddfbfSEd Maste   }
563ac7ddfbfSEd Maste 
564ac7ddfbfSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)565435933ddSDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
566ac7ddfbfSEd Maste     result.SetStatus(eReturnStatusSuccessFinishResult);
567ac7ddfbfSEd Maste 
568ac7ddfbfSEd Maste     const bool will_modify = false;
569ac7ddfbfSEd Maste     const size_t argc = args.GetArgumentCount();
570435933ddSDimitry Andric     if (argc > 0) {
571ac7ddfbfSEd Maste       const bool dump_qualified_name = true;
572ac7ddfbfSEd Maste 
573435933ddSDimitry Andric       // TODO: Convert to StringRef based enumeration.  Requires converting
574435933ddSDimitry Andric       // GetPropertyAtPath first.
575435933ddSDimitry Andric       for (size_t i = 0; i < argc; ++i) {
576ac7ddfbfSEd Maste         const char *property_path = args.GetArgumentAtIndex(i);
577ac7ddfbfSEd Maste 
578435933ddSDimitry Andric         const Property *property =
579435933ddSDimitry Andric             m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath(
580435933ddSDimitry Andric                 &m_exe_ctx, will_modify, property_path);
581ac7ddfbfSEd Maste 
582435933ddSDimitry Andric         if (property) {
583435933ddSDimitry Andric           property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
584435933ddSDimitry Andric                                     dump_qualified_name);
585435933ddSDimitry Andric         } else {
586435933ddSDimitry Andric           result.AppendErrorWithFormat("invalid property path '%s'",
587435933ddSDimitry Andric                                        property_path);
588ac7ddfbfSEd Maste           result.SetStatus(eReturnStatusFailed);
589ac7ddfbfSEd Maste         }
590ac7ddfbfSEd Maste       }
591435933ddSDimitry Andric     } else {
592435933ddSDimitry Andric       m_interpreter.GetDebugger().DumpAllDescriptions(m_interpreter,
593435933ddSDimitry Andric                                                       result.GetOutputStream());
594ac7ddfbfSEd Maste     }
595ac7ddfbfSEd Maste 
596ac7ddfbfSEd Maste     return result.Succeeded();
597ac7ddfbfSEd Maste   }
598ac7ddfbfSEd Maste };
599ac7ddfbfSEd Maste 
600ac7ddfbfSEd Maste //-------------------------------------------------------------------------
601ac7ddfbfSEd Maste // CommandObjectSettingsRemove
602ac7ddfbfSEd Maste //-------------------------------------------------------------------------
603ac7ddfbfSEd Maste 
604435933ddSDimitry Andric class CommandObjectSettingsRemove : public CommandObjectRaw {
605ac7ddfbfSEd Maste public:
CommandObjectSettingsRemove(CommandInterpreter & interpreter)6064bb0738eSEd Maste   CommandObjectSettingsRemove(CommandInterpreter &interpreter)
6074bb0738eSEd Maste       : CommandObjectRaw(interpreter, "settings remove",
608435933ddSDimitry Andric                          "Remove a value from a setting, specified by array "
609435933ddSDimitry Andric                          "index or dictionary key.") {
610ac7ddfbfSEd Maste     CommandArgumentEntry arg1;
611ac7ddfbfSEd Maste     CommandArgumentEntry arg2;
612ac7ddfbfSEd Maste     CommandArgumentData var_name_arg;
613ac7ddfbfSEd Maste     CommandArgumentData index_arg;
614ac7ddfbfSEd Maste     CommandArgumentData key_arg;
615ac7ddfbfSEd Maste 
616ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
617ac7ddfbfSEd Maste     var_name_arg.arg_type = eArgTypeSettingVariableName;
618ac7ddfbfSEd Maste     var_name_arg.arg_repetition = eArgRepeatPlain;
619ac7ddfbfSEd Maste 
620435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
621435933ddSDimitry Andric     // argument entry.
622ac7ddfbfSEd Maste     arg1.push_back(var_name_arg);
623ac7ddfbfSEd Maste 
624ac7ddfbfSEd Maste     // Define the first variant of this arg.
625ac7ddfbfSEd Maste     index_arg.arg_type = eArgTypeSettingIndex;
626ac7ddfbfSEd Maste     index_arg.arg_repetition = eArgRepeatPlain;
627ac7ddfbfSEd Maste 
628ac7ddfbfSEd Maste     // Define the second variant of this arg.
629ac7ddfbfSEd Maste     key_arg.arg_type = eArgTypeSettingKey;
630ac7ddfbfSEd Maste     key_arg.arg_repetition = eArgRepeatPlain;
631ac7ddfbfSEd Maste 
632ac7ddfbfSEd Maste     // Push both variants into this arg
633ac7ddfbfSEd Maste     arg2.push_back(index_arg);
634ac7ddfbfSEd Maste     arg2.push_back(key_arg);
635ac7ddfbfSEd Maste 
636ac7ddfbfSEd Maste     // Push the data for the first argument into the m_arguments vector.
637ac7ddfbfSEd Maste     m_arguments.push_back(arg1);
638ac7ddfbfSEd Maste     m_arguments.push_back(arg2);
639ac7ddfbfSEd Maste   }
640ac7ddfbfSEd Maste 
6414bb0738eSEd Maste   ~CommandObjectSettingsRemove() override = default;
642ac7ddfbfSEd Maste 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)6434ba319b5SDimitry Andric   int HandleArgumentCompletion(
6444ba319b5SDimitry Andric       CompletionRequest &request,
6454ba319b5SDimitry Andric       OptionElementVector &opt_element_vector) override {
6464ba319b5SDimitry Andric     if (request.GetCursorIndex() < 2)
647435933ddSDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
648435933ddSDimitry Andric           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
6494ba319b5SDimitry Andric           request, nullptr);
6504ba319b5SDimitry Andric     return request.GetNumberOfMatches();
651ac7ddfbfSEd Maste   }
652ac7ddfbfSEd Maste 
653ac7ddfbfSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)6544ba319b5SDimitry Andric   bool DoExecute(llvm::StringRef command,
6554ba319b5SDimitry Andric                  CommandReturnObject &result) override {
656ac7ddfbfSEd Maste     result.SetStatus(eReturnStatusSuccessFinishNoResult);
657ac7ddfbfSEd Maste 
658ac7ddfbfSEd Maste     Args cmd_args(command);
659ac7ddfbfSEd Maste 
660ac7ddfbfSEd Maste     // Process possible options.
661ac7ddfbfSEd Maste     if (!ParseOptions(cmd_args, result))
662ac7ddfbfSEd Maste       return false;
663ac7ddfbfSEd Maste 
664ac7ddfbfSEd Maste     const size_t argc = cmd_args.GetArgumentCount();
665435933ddSDimitry Andric     if (argc == 0) {
666435933ddSDimitry Andric       result.AppendError("'settings set' takes an array or dictionary item, or "
667435933ddSDimitry Andric                          "an array followed by one or more indexes, or a "
668435933ddSDimitry Andric                          "dictionary followed by one or more key names to "
669435933ddSDimitry Andric                          "remove");
670ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
671ac7ddfbfSEd Maste       return false;
672ac7ddfbfSEd Maste     }
673ac7ddfbfSEd Maste 
674ac7ddfbfSEd Maste     const char *var_name = cmd_args.GetArgumentAtIndex(0);
675435933ddSDimitry Andric     if ((var_name == nullptr) || (var_name[0] == '\0')) {
676435933ddSDimitry Andric       result.AppendError(
677435933ddSDimitry Andric           "'settings set' command requires a valid variable name");
678ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
679ac7ddfbfSEd Maste       return false;
680ac7ddfbfSEd Maste     }
681ac7ddfbfSEd Maste 
682ac7ddfbfSEd Maste     // Split the raw command into var_name and value pair.
683ac7ddfbfSEd Maste     llvm::StringRef raw_str(command);
684ac7ddfbfSEd Maste     std::string var_value_string = raw_str.split(var_name).second.str();
685435933ddSDimitry Andric     const char *var_value_cstr =
686435933ddSDimitry Andric         Args::StripSpaces(var_value_string, true, true, false);
687ac7ddfbfSEd Maste 
6885517e702SDimitry Andric     Status error(m_interpreter.GetDebugger().SetPropertyValue(
689435933ddSDimitry Andric         &m_exe_ctx, eVarSetOperationRemove, var_name, var_value_cstr));
690435933ddSDimitry Andric     if (error.Fail()) {
691ac7ddfbfSEd Maste       result.AppendError(error.AsCString());
692ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
693ac7ddfbfSEd Maste       return false;
694ac7ddfbfSEd Maste     }
695ac7ddfbfSEd Maste 
696ac7ddfbfSEd Maste     return result.Succeeded();
697ac7ddfbfSEd Maste   }
698ac7ddfbfSEd Maste };
699ac7ddfbfSEd Maste 
700ac7ddfbfSEd Maste //-------------------------------------------------------------------------
701ac7ddfbfSEd Maste // CommandObjectSettingsReplace
702ac7ddfbfSEd Maste //-------------------------------------------------------------------------
703ac7ddfbfSEd Maste 
704435933ddSDimitry Andric class CommandObjectSettingsReplace : public CommandObjectRaw {
705ac7ddfbfSEd Maste public:
CommandObjectSettingsReplace(CommandInterpreter & interpreter)7064bb0738eSEd Maste   CommandObjectSettingsReplace(CommandInterpreter &interpreter)
7074bb0738eSEd Maste       : CommandObjectRaw(interpreter, "settings replace",
708435933ddSDimitry Andric                          "Replace the debugger setting value specified by "
709435933ddSDimitry Andric                          "array index or dictionary key.") {
710ac7ddfbfSEd Maste     CommandArgumentEntry arg1;
711ac7ddfbfSEd Maste     CommandArgumentEntry arg2;
712ac7ddfbfSEd Maste     CommandArgumentEntry arg3;
713ac7ddfbfSEd Maste     CommandArgumentData var_name_arg;
714ac7ddfbfSEd Maste     CommandArgumentData index_arg;
715ac7ddfbfSEd Maste     CommandArgumentData key_arg;
716ac7ddfbfSEd Maste     CommandArgumentData value_arg;
717ac7ddfbfSEd Maste 
718ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
719ac7ddfbfSEd Maste     var_name_arg.arg_type = eArgTypeSettingVariableName;
720ac7ddfbfSEd Maste     var_name_arg.arg_repetition = eArgRepeatPlain;
721ac7ddfbfSEd Maste 
722435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
723435933ddSDimitry Andric     // argument entry.
724ac7ddfbfSEd Maste     arg1.push_back(var_name_arg);
725ac7ddfbfSEd Maste 
726ac7ddfbfSEd Maste     // Define the first (variant of this arg.
727ac7ddfbfSEd Maste     index_arg.arg_type = eArgTypeSettingIndex;
728ac7ddfbfSEd Maste     index_arg.arg_repetition = eArgRepeatPlain;
729ac7ddfbfSEd Maste 
730ac7ddfbfSEd Maste     // Define the second (variant of this arg.
731ac7ddfbfSEd Maste     key_arg.arg_type = eArgTypeSettingKey;
732ac7ddfbfSEd Maste     key_arg.arg_repetition = eArgRepeatPlain;
733ac7ddfbfSEd Maste 
734ac7ddfbfSEd Maste     // Put both variants into this arg
735ac7ddfbfSEd Maste     arg2.push_back(index_arg);
736ac7ddfbfSEd Maste     arg2.push_back(key_arg);
737ac7ddfbfSEd Maste 
738ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
739ac7ddfbfSEd Maste     value_arg.arg_type = eArgTypeValue;
740ac7ddfbfSEd Maste     value_arg.arg_repetition = eArgRepeatPlain;
741ac7ddfbfSEd Maste 
742435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
743435933ddSDimitry Andric     // argument entry.
744ac7ddfbfSEd Maste     arg3.push_back(value_arg);
745ac7ddfbfSEd Maste 
746ac7ddfbfSEd Maste     // Push the data for the first argument into the m_arguments vector.
747ac7ddfbfSEd Maste     m_arguments.push_back(arg1);
748ac7ddfbfSEd Maste     m_arguments.push_back(arg2);
749ac7ddfbfSEd Maste     m_arguments.push_back(arg3);
750ac7ddfbfSEd Maste   }
751ac7ddfbfSEd Maste 
7524bb0738eSEd Maste   ~CommandObjectSettingsReplace() override = default;
753ac7ddfbfSEd Maste 
754435933ddSDimitry Andric   // Overrides base class's behavior where WantsCompletion =
755435933ddSDimitry Andric   // !WantsRawCommandString.
WantsCompletion()756435933ddSDimitry Andric   bool WantsCompletion() override { return true; }
757ac7ddfbfSEd Maste 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)7584ba319b5SDimitry Andric   int HandleArgumentCompletion(
7594ba319b5SDimitry Andric       CompletionRequest &request,
7604ba319b5SDimitry Andric       OptionElementVector &opt_element_vector) override {
761ac7ddfbfSEd Maste     // Attempting to complete variable name
7624ba319b5SDimitry Andric     if (request.GetCursorIndex() < 2)
763435933ddSDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
764435933ddSDimitry Andric           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
7654ba319b5SDimitry Andric           request, nullptr);
766ac7ddfbfSEd Maste 
7674ba319b5SDimitry Andric     return request.GetNumberOfMatches();
768ac7ddfbfSEd Maste   }
769ac7ddfbfSEd Maste 
770ac7ddfbfSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)7714ba319b5SDimitry Andric   bool DoExecute(llvm::StringRef command,
7724ba319b5SDimitry Andric                  CommandReturnObject &result) override {
773ac7ddfbfSEd Maste     result.SetStatus(eReturnStatusSuccessFinishNoResult);
774ac7ddfbfSEd Maste 
775ac7ddfbfSEd Maste     Args cmd_args(command);
776ac7ddfbfSEd Maste     const char *var_name = cmd_args.GetArgumentAtIndex(0);
777435933ddSDimitry Andric     if ((var_name == nullptr) || (var_name[0] == '\0')) {
778435933ddSDimitry Andric       result.AppendError("'settings replace' command requires a valid variable "
779435933ddSDimitry Andric                          "name; No value supplied");
780ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
781ac7ddfbfSEd Maste       return false;
782ac7ddfbfSEd Maste     }
783ac7ddfbfSEd Maste 
784ac7ddfbfSEd Maste     // Split the raw command into var_name, index_value, and value triple.
785ac7ddfbfSEd Maste     llvm::StringRef raw_str(command);
786ac7ddfbfSEd Maste     std::string var_value_string = raw_str.split(var_name).second.str();
787435933ddSDimitry Andric     const char *var_value_cstr =
788435933ddSDimitry Andric         Args::StripSpaces(var_value_string, true, true, false);
789ac7ddfbfSEd Maste 
7905517e702SDimitry Andric     Status error(m_interpreter.GetDebugger().SetPropertyValue(
791435933ddSDimitry Andric         &m_exe_ctx, eVarSetOperationReplace, var_name, var_value_cstr));
792435933ddSDimitry Andric     if (error.Fail()) {
793ac7ddfbfSEd Maste       result.AppendError(error.AsCString());
794ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
795ac7ddfbfSEd Maste       return false;
796435933ddSDimitry Andric     } else {
797ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusSuccessFinishNoResult);
798ac7ddfbfSEd Maste     }
799ac7ddfbfSEd Maste 
800ac7ddfbfSEd Maste     return result.Succeeded();
801ac7ddfbfSEd Maste   }
802ac7ddfbfSEd Maste };
803ac7ddfbfSEd Maste 
804ac7ddfbfSEd Maste //-------------------------------------------------------------------------
805ac7ddfbfSEd Maste // CommandObjectSettingsInsertBefore
806ac7ddfbfSEd Maste //-------------------------------------------------------------------------
807ac7ddfbfSEd Maste 
808435933ddSDimitry Andric class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
809ac7ddfbfSEd Maste public:
CommandObjectSettingsInsertBefore(CommandInterpreter & interpreter)8104bb0738eSEd Maste   CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
811435933ddSDimitry Andric       : CommandObjectRaw(interpreter, "settings insert-before",
812435933ddSDimitry Andric                          "Insert one or more values into an debugger array "
8134bb0738eSEd Maste                          "setting immediately before the specified element "
814435933ddSDimitry Andric                          "index.") {
815ac7ddfbfSEd Maste     CommandArgumentEntry arg1;
816ac7ddfbfSEd Maste     CommandArgumentEntry arg2;
817ac7ddfbfSEd Maste     CommandArgumentEntry arg3;
818ac7ddfbfSEd Maste     CommandArgumentData var_name_arg;
819ac7ddfbfSEd Maste     CommandArgumentData index_arg;
820ac7ddfbfSEd Maste     CommandArgumentData value_arg;
821ac7ddfbfSEd Maste 
822ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
823ac7ddfbfSEd Maste     var_name_arg.arg_type = eArgTypeSettingVariableName;
824ac7ddfbfSEd Maste     var_name_arg.arg_repetition = eArgRepeatPlain;
825ac7ddfbfSEd Maste 
826435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
827435933ddSDimitry Andric     // argument entry.
828ac7ddfbfSEd Maste     arg1.push_back(var_name_arg);
829ac7ddfbfSEd Maste 
830ac7ddfbfSEd Maste     // Define the first (variant of this arg.
831ac7ddfbfSEd Maste     index_arg.arg_type = eArgTypeSettingIndex;
832ac7ddfbfSEd Maste     index_arg.arg_repetition = eArgRepeatPlain;
833ac7ddfbfSEd Maste 
834435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
835435933ddSDimitry Andric     // argument entry.
836ac7ddfbfSEd Maste     arg2.push_back(index_arg);
837ac7ddfbfSEd Maste 
838ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
839ac7ddfbfSEd Maste     value_arg.arg_type = eArgTypeValue;
840ac7ddfbfSEd Maste     value_arg.arg_repetition = eArgRepeatPlain;
841ac7ddfbfSEd Maste 
842435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
843435933ddSDimitry Andric     // argument entry.
844ac7ddfbfSEd Maste     arg3.push_back(value_arg);
845ac7ddfbfSEd Maste 
846ac7ddfbfSEd Maste     // Push the data for the first argument into the m_arguments vector.
847ac7ddfbfSEd Maste     m_arguments.push_back(arg1);
848ac7ddfbfSEd Maste     m_arguments.push_back(arg2);
849ac7ddfbfSEd Maste     m_arguments.push_back(arg3);
850ac7ddfbfSEd Maste   }
851ac7ddfbfSEd Maste 
8524bb0738eSEd Maste   ~CommandObjectSettingsInsertBefore() override = default;
853ac7ddfbfSEd Maste 
854435933ddSDimitry Andric   // Overrides base class's behavior where WantsCompletion =
855435933ddSDimitry Andric   // !WantsRawCommandString.
WantsCompletion()856435933ddSDimitry Andric   bool WantsCompletion() override { return true; }
857ac7ddfbfSEd Maste 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)8584ba319b5SDimitry Andric   int HandleArgumentCompletion(
8594ba319b5SDimitry Andric       CompletionRequest &request,
8604ba319b5SDimitry Andric       OptionElementVector &opt_element_vector) override {
861ac7ddfbfSEd Maste     // Attempting to complete variable name
8624ba319b5SDimitry Andric     if (request.GetCursorIndex() < 2)
863435933ddSDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
864435933ddSDimitry Andric           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
8654ba319b5SDimitry Andric           request, nullptr);
866ac7ddfbfSEd Maste 
8674ba319b5SDimitry Andric     return request.GetNumberOfMatches();
868ac7ddfbfSEd Maste   }
869ac7ddfbfSEd Maste 
870ac7ddfbfSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)8714ba319b5SDimitry Andric   bool DoExecute(llvm::StringRef command,
8724ba319b5SDimitry Andric                  CommandReturnObject &result) override {
873ac7ddfbfSEd Maste     result.SetStatus(eReturnStatusSuccessFinishNoResult);
874ac7ddfbfSEd Maste 
875ac7ddfbfSEd Maste     Args cmd_args(command);
876ac7ddfbfSEd Maste     const size_t argc = cmd_args.GetArgumentCount();
877ac7ddfbfSEd Maste 
878435933ddSDimitry Andric     if (argc < 3) {
879ac7ddfbfSEd Maste       result.AppendError("'settings insert-before' takes more arguments");
880ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
881ac7ddfbfSEd Maste       return false;
882ac7ddfbfSEd Maste     }
883ac7ddfbfSEd Maste 
884ac7ddfbfSEd Maste     const char *var_name = cmd_args.GetArgumentAtIndex(0);
885435933ddSDimitry Andric     if ((var_name == nullptr) || (var_name[0] == '\0')) {
886435933ddSDimitry Andric       result.AppendError("'settings insert-before' command requires a valid "
887435933ddSDimitry Andric                          "variable name; No value supplied");
888ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
889ac7ddfbfSEd Maste       return false;
890ac7ddfbfSEd Maste     }
891ac7ddfbfSEd Maste 
892ac7ddfbfSEd Maste     // Split the raw command into var_name, index_value, and value triple.
893ac7ddfbfSEd Maste     llvm::StringRef raw_str(command);
894ac7ddfbfSEd Maste     std::string var_value_string = raw_str.split(var_name).second.str();
895435933ddSDimitry Andric     const char *var_value_cstr =
896435933ddSDimitry Andric         Args::StripSpaces(var_value_string, true, true, false);
897ac7ddfbfSEd Maste 
8985517e702SDimitry Andric     Status error(m_interpreter.GetDebugger().SetPropertyValue(
899435933ddSDimitry Andric         &m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value_cstr));
900435933ddSDimitry Andric     if (error.Fail()) {
901ac7ddfbfSEd Maste       result.AppendError(error.AsCString());
902ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
903ac7ddfbfSEd Maste       return false;
904ac7ddfbfSEd Maste     }
905ac7ddfbfSEd Maste 
906ac7ddfbfSEd Maste     return result.Succeeded();
907ac7ddfbfSEd Maste   }
908ac7ddfbfSEd Maste };
909ac7ddfbfSEd Maste 
910ac7ddfbfSEd Maste //-------------------------------------------------------------------------
911ac7ddfbfSEd Maste // CommandObjectSettingInsertAfter
912ac7ddfbfSEd Maste //-------------------------------------------------------------------------
913ac7ddfbfSEd Maste 
914435933ddSDimitry Andric class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
915ac7ddfbfSEd Maste public:
CommandObjectSettingsInsertAfter(CommandInterpreter & interpreter)9164bb0738eSEd Maste   CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
917435933ddSDimitry Andric       : CommandObjectRaw(interpreter, "settings insert-after",
918435933ddSDimitry Andric                          "Insert one or more values into a debugger array "
919435933ddSDimitry Andric                          "settings after the specified element index.") {
920ac7ddfbfSEd Maste     CommandArgumentEntry arg1;
921ac7ddfbfSEd Maste     CommandArgumentEntry arg2;
922ac7ddfbfSEd Maste     CommandArgumentEntry arg3;
923ac7ddfbfSEd Maste     CommandArgumentData var_name_arg;
924ac7ddfbfSEd Maste     CommandArgumentData index_arg;
925ac7ddfbfSEd Maste     CommandArgumentData value_arg;
926ac7ddfbfSEd Maste 
927ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
928ac7ddfbfSEd Maste     var_name_arg.arg_type = eArgTypeSettingVariableName;
929ac7ddfbfSEd Maste     var_name_arg.arg_repetition = eArgRepeatPlain;
930ac7ddfbfSEd Maste 
931435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
932435933ddSDimitry Andric     // argument entry.
933ac7ddfbfSEd Maste     arg1.push_back(var_name_arg);
934ac7ddfbfSEd Maste 
935ac7ddfbfSEd Maste     // Define the first (variant of this arg.
936ac7ddfbfSEd Maste     index_arg.arg_type = eArgTypeSettingIndex;
937ac7ddfbfSEd Maste     index_arg.arg_repetition = eArgRepeatPlain;
938ac7ddfbfSEd Maste 
939435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
940435933ddSDimitry Andric     // argument entry.
941ac7ddfbfSEd Maste     arg2.push_back(index_arg);
942ac7ddfbfSEd Maste 
943ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
944ac7ddfbfSEd Maste     value_arg.arg_type = eArgTypeValue;
945ac7ddfbfSEd Maste     value_arg.arg_repetition = eArgRepeatPlain;
946ac7ddfbfSEd Maste 
947435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
948435933ddSDimitry Andric     // argument entry.
949ac7ddfbfSEd Maste     arg3.push_back(value_arg);
950ac7ddfbfSEd Maste 
951ac7ddfbfSEd Maste     // Push the data for the first argument into the m_arguments vector.
952ac7ddfbfSEd Maste     m_arguments.push_back(arg1);
953ac7ddfbfSEd Maste     m_arguments.push_back(arg2);
954ac7ddfbfSEd Maste     m_arguments.push_back(arg3);
955ac7ddfbfSEd Maste   }
956ac7ddfbfSEd Maste 
9574bb0738eSEd Maste   ~CommandObjectSettingsInsertAfter() override = default;
958ac7ddfbfSEd Maste 
959435933ddSDimitry Andric   // Overrides base class's behavior where WantsCompletion =
960435933ddSDimitry Andric   // !WantsRawCommandString.
WantsCompletion()961435933ddSDimitry Andric   bool WantsCompletion() override { return true; }
962ac7ddfbfSEd Maste 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)9634ba319b5SDimitry Andric   int HandleArgumentCompletion(
9644ba319b5SDimitry Andric       CompletionRequest &request,
9654ba319b5SDimitry Andric       OptionElementVector &opt_element_vector) override {
966ac7ddfbfSEd Maste     // Attempting to complete variable name
9674ba319b5SDimitry Andric     if (request.GetCursorIndex() < 2)
968435933ddSDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
969435933ddSDimitry Andric           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
9704ba319b5SDimitry Andric           request, nullptr);
971ac7ddfbfSEd Maste 
9724ba319b5SDimitry Andric     return request.GetNumberOfMatches();
973ac7ddfbfSEd Maste   }
974ac7ddfbfSEd Maste 
975ac7ddfbfSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)9764ba319b5SDimitry Andric   bool DoExecute(llvm::StringRef command,
9774ba319b5SDimitry Andric                  CommandReturnObject &result) override {
978ac7ddfbfSEd Maste     result.SetStatus(eReturnStatusSuccessFinishNoResult);
979ac7ddfbfSEd Maste 
980ac7ddfbfSEd Maste     Args cmd_args(command);
981ac7ddfbfSEd Maste     const size_t argc = cmd_args.GetArgumentCount();
982ac7ddfbfSEd Maste 
983435933ddSDimitry Andric     if (argc < 3) {
984ac7ddfbfSEd Maste       result.AppendError("'settings insert-after' takes more arguments");
985ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
986ac7ddfbfSEd Maste       return false;
987ac7ddfbfSEd Maste     }
988ac7ddfbfSEd Maste 
989ac7ddfbfSEd Maste     const char *var_name = cmd_args.GetArgumentAtIndex(0);
990435933ddSDimitry Andric     if ((var_name == nullptr) || (var_name[0] == '\0')) {
991435933ddSDimitry Andric       result.AppendError("'settings insert-after' command requires a valid "
992435933ddSDimitry Andric                          "variable name; No value supplied");
993ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
994ac7ddfbfSEd Maste       return false;
995ac7ddfbfSEd Maste     }
996ac7ddfbfSEd Maste 
997ac7ddfbfSEd Maste     // Split the raw command into var_name, index_value, and value triple.
998ac7ddfbfSEd Maste     llvm::StringRef raw_str(command);
999ac7ddfbfSEd Maste     std::string var_value_string = raw_str.split(var_name).second.str();
1000435933ddSDimitry Andric     const char *var_value_cstr =
1001435933ddSDimitry Andric         Args::StripSpaces(var_value_string, true, true, false);
1002ac7ddfbfSEd Maste 
10035517e702SDimitry Andric     Status error(m_interpreter.GetDebugger().SetPropertyValue(
1004435933ddSDimitry Andric         &m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value_cstr));
1005435933ddSDimitry Andric     if (error.Fail()) {
1006ac7ddfbfSEd Maste       result.AppendError(error.AsCString());
1007ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
1008ac7ddfbfSEd Maste       return false;
1009ac7ddfbfSEd Maste     }
1010ac7ddfbfSEd Maste 
1011ac7ddfbfSEd Maste     return result.Succeeded();
1012ac7ddfbfSEd Maste   }
1013ac7ddfbfSEd Maste };
1014ac7ddfbfSEd Maste 
1015ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1016ac7ddfbfSEd Maste // CommandObjectSettingsAppend
1017ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1018ac7ddfbfSEd Maste 
1019435933ddSDimitry Andric class CommandObjectSettingsAppend : public CommandObjectRaw {
1020ac7ddfbfSEd Maste public:
CommandObjectSettingsAppend(CommandInterpreter & interpreter)10214bb0738eSEd Maste   CommandObjectSettingsAppend(CommandInterpreter &interpreter)
10224bb0738eSEd Maste       : CommandObjectRaw(interpreter, "settings append",
1023435933ddSDimitry Andric                          "Append one or more values to a debugger array, "
1024435933ddSDimitry Andric                          "dictionary, or string setting.") {
1025ac7ddfbfSEd Maste     CommandArgumentEntry arg1;
1026ac7ddfbfSEd Maste     CommandArgumentEntry arg2;
1027ac7ddfbfSEd Maste     CommandArgumentData var_name_arg;
1028ac7ddfbfSEd Maste     CommandArgumentData value_arg;
1029ac7ddfbfSEd Maste 
1030ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
1031ac7ddfbfSEd Maste     var_name_arg.arg_type = eArgTypeSettingVariableName;
1032ac7ddfbfSEd Maste     var_name_arg.arg_repetition = eArgRepeatPlain;
1033ac7ddfbfSEd Maste 
1034435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
1035435933ddSDimitry Andric     // argument entry.
1036ac7ddfbfSEd Maste     arg1.push_back(var_name_arg);
1037ac7ddfbfSEd Maste 
1038ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
1039ac7ddfbfSEd Maste     value_arg.arg_type = eArgTypeValue;
1040ac7ddfbfSEd Maste     value_arg.arg_repetition = eArgRepeatPlain;
1041ac7ddfbfSEd Maste 
1042435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
1043435933ddSDimitry Andric     // argument entry.
1044ac7ddfbfSEd Maste     arg2.push_back(value_arg);
1045ac7ddfbfSEd Maste 
1046ac7ddfbfSEd Maste     // Push the data for the first argument into the m_arguments vector.
1047ac7ddfbfSEd Maste     m_arguments.push_back(arg1);
1048ac7ddfbfSEd Maste     m_arguments.push_back(arg2);
1049ac7ddfbfSEd Maste   }
1050ac7ddfbfSEd Maste 
10514bb0738eSEd Maste   ~CommandObjectSettingsAppend() override = default;
1052ac7ddfbfSEd Maste 
1053435933ddSDimitry Andric   // Overrides base class's behavior where WantsCompletion =
1054435933ddSDimitry Andric   // !WantsRawCommandString.
WantsCompletion()1055435933ddSDimitry Andric   bool WantsCompletion() override { return true; }
1056ac7ddfbfSEd Maste 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)10574ba319b5SDimitry Andric   int HandleArgumentCompletion(
10584ba319b5SDimitry Andric       CompletionRequest &request,
10594ba319b5SDimitry Andric       OptionElementVector &opt_element_vector) override {
1060ac7ddfbfSEd Maste     // Attempting to complete variable name
10614ba319b5SDimitry Andric     if (request.GetCursorIndex() < 2)
1062435933ddSDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
1063435933ddSDimitry Andric           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
10644ba319b5SDimitry Andric           request, nullptr);
1065ac7ddfbfSEd Maste 
10664ba319b5SDimitry Andric     return request.GetNumberOfMatches();
1067ac7ddfbfSEd Maste   }
1068ac7ddfbfSEd Maste 
1069ac7ddfbfSEd Maste protected:
DoExecute(llvm::StringRef command,CommandReturnObject & result)10704ba319b5SDimitry Andric   bool DoExecute(llvm::StringRef command,
10714ba319b5SDimitry Andric                  CommandReturnObject &result) override {
1072ac7ddfbfSEd Maste     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1073ac7ddfbfSEd Maste     Args cmd_args(command);
1074ac7ddfbfSEd Maste     const size_t argc = cmd_args.GetArgumentCount();
1075ac7ddfbfSEd Maste 
1076435933ddSDimitry Andric     if (argc < 2) {
1077ac7ddfbfSEd Maste       result.AppendError("'settings append' takes more arguments");
1078ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
1079ac7ddfbfSEd Maste       return false;
1080ac7ddfbfSEd Maste     }
1081ac7ddfbfSEd Maste 
1082ac7ddfbfSEd Maste     const char *var_name = cmd_args.GetArgumentAtIndex(0);
1083435933ddSDimitry Andric     if ((var_name == nullptr) || (var_name[0] == '\0')) {
1084435933ddSDimitry Andric       result.AppendError("'settings append' command requires a valid variable "
1085435933ddSDimitry Andric                          "name; No value supplied");
1086ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
1087ac7ddfbfSEd Maste       return false;
1088ac7ddfbfSEd Maste     }
1089ac7ddfbfSEd Maste 
10904ba319b5SDimitry Andric     // Do not perform cmd_args.Shift() since StringRef is manipulating the raw
10914ba319b5SDimitry Andric     // character string later on.
1092ac7ddfbfSEd Maste 
1093ac7ddfbfSEd Maste     // Split the raw command into var_name and value pair.
1094ac7ddfbfSEd Maste     llvm::StringRef raw_str(command);
1095ac7ddfbfSEd Maste     std::string var_value_string = raw_str.split(var_name).second.str();
1096435933ddSDimitry Andric     const char *var_value_cstr =
1097435933ddSDimitry Andric         Args::StripSpaces(var_value_string, true, true, false);
1098ac7ddfbfSEd Maste 
10995517e702SDimitry Andric     Status error(m_interpreter.GetDebugger().SetPropertyValue(
1100435933ddSDimitry Andric         &m_exe_ctx, eVarSetOperationAppend, var_name, var_value_cstr));
1101435933ddSDimitry Andric     if (error.Fail()) {
1102ac7ddfbfSEd Maste       result.AppendError(error.AsCString());
1103ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
1104ac7ddfbfSEd Maste       return false;
1105ac7ddfbfSEd Maste     }
1106ac7ddfbfSEd Maste 
1107ac7ddfbfSEd Maste     return result.Succeeded();
1108ac7ddfbfSEd Maste   }
1109ac7ddfbfSEd Maste };
1110ac7ddfbfSEd Maste 
1111ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1112ac7ddfbfSEd Maste // CommandObjectSettingsClear
1113ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1114ac7ddfbfSEd Maste 
1115435933ddSDimitry Andric class CommandObjectSettingsClear : public CommandObjectParsed {
1116ac7ddfbfSEd Maste public:
CommandObjectSettingsClear(CommandInterpreter & interpreter)11174bb0738eSEd Maste   CommandObjectSettingsClear(CommandInterpreter &interpreter)
1118435933ddSDimitry Andric       : CommandObjectParsed(
1119435933ddSDimitry Andric             interpreter, "settings clear",
1120435933ddSDimitry Andric             "Clear a debugger setting array, dictionary, or string.", nullptr) {
1121ac7ddfbfSEd Maste     CommandArgumentEntry arg;
1122ac7ddfbfSEd Maste     CommandArgumentData var_name_arg;
1123ac7ddfbfSEd Maste 
1124ac7ddfbfSEd Maste     // Define the first (and only) variant of this arg.
1125ac7ddfbfSEd Maste     var_name_arg.arg_type = eArgTypeSettingVariableName;
1126ac7ddfbfSEd Maste     var_name_arg.arg_repetition = eArgRepeatPlain;
1127ac7ddfbfSEd Maste 
1128435933ddSDimitry Andric     // There is only one variant this argument could be; put it into the
1129435933ddSDimitry Andric     // argument entry.
1130ac7ddfbfSEd Maste     arg.push_back(var_name_arg);
1131ac7ddfbfSEd Maste 
1132ac7ddfbfSEd Maste     // Push the data for the first argument into the m_arguments vector.
1133ac7ddfbfSEd Maste     m_arguments.push_back(arg);
1134ac7ddfbfSEd Maste   }
1135ac7ddfbfSEd Maste 
11364bb0738eSEd Maste   ~CommandObjectSettingsClear() override = default;
1137ac7ddfbfSEd Maste 
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)11384ba319b5SDimitry Andric   int HandleArgumentCompletion(
11394ba319b5SDimitry Andric       CompletionRequest &request,
11404ba319b5SDimitry Andric       OptionElementVector &opt_element_vector) override {
1141ac7ddfbfSEd Maste     // Attempting to complete variable name
11424ba319b5SDimitry Andric     if (request.GetCursorIndex() < 2)
1143435933ddSDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
1144435933ddSDimitry Andric           GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion,
11454ba319b5SDimitry Andric           request, nullptr);
1146ac7ddfbfSEd Maste 
11474ba319b5SDimitry Andric     return request.GetNumberOfMatches();
1148ac7ddfbfSEd Maste   }
1149ac7ddfbfSEd Maste 
1150ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1151435933ddSDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
1152ac7ddfbfSEd Maste     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1153ac7ddfbfSEd Maste     const size_t argc = command.GetArgumentCount();
1154ac7ddfbfSEd Maste 
1155435933ddSDimitry Andric     if (argc != 1) {
11560127ef0fSEd Maste       result.AppendError("'settings clear' takes exactly one argument");
1157ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
1158ac7ddfbfSEd Maste       return false;
1159ac7ddfbfSEd Maste     }
1160ac7ddfbfSEd Maste 
1161ac7ddfbfSEd Maste     const char *var_name = command.GetArgumentAtIndex(0);
1162435933ddSDimitry Andric     if ((var_name == nullptr) || (var_name[0] == '\0')) {
1163435933ddSDimitry Andric       result.AppendError("'settings clear' command requires a valid variable "
1164435933ddSDimitry Andric                          "name; No value supplied");
1165ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
1166ac7ddfbfSEd Maste       return false;
1167ac7ddfbfSEd Maste     }
1168ac7ddfbfSEd Maste 
11695517e702SDimitry Andric     Status error(m_interpreter.GetDebugger().SetPropertyValue(
1170435933ddSDimitry Andric         &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1171435933ddSDimitry Andric     if (error.Fail()) {
1172ac7ddfbfSEd Maste       result.AppendError(error.AsCString());
1173ac7ddfbfSEd Maste       result.SetStatus(eReturnStatusFailed);
1174ac7ddfbfSEd Maste       return false;
1175ac7ddfbfSEd Maste     }
1176ac7ddfbfSEd Maste 
1177ac7ddfbfSEd Maste     return result.Succeeded();
1178ac7ddfbfSEd Maste   }
1179ac7ddfbfSEd Maste };
1180ac7ddfbfSEd Maste 
1181ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1182ac7ddfbfSEd Maste // CommandObjectMultiwordSettings
1183ac7ddfbfSEd Maste //-------------------------------------------------------------------------
1184ac7ddfbfSEd Maste 
CommandObjectMultiwordSettings(CommandInterpreter & interpreter)1185435933ddSDimitry Andric CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1186435933ddSDimitry Andric     CommandInterpreter &interpreter)
1187435933ddSDimitry Andric     : CommandObjectMultiword(interpreter, "settings",
1188435933ddSDimitry Andric                              "Commands for managing LLDB settings.",
1189435933ddSDimitry Andric                              "settings <subcommand> [<command-options>]") {
1190435933ddSDimitry Andric   LoadSubCommand("set",
1191435933ddSDimitry Andric                  CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1192435933ddSDimitry Andric   LoadSubCommand("show",
1193435933ddSDimitry Andric                  CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1194435933ddSDimitry Andric   LoadSubCommand("list",
1195435933ddSDimitry Andric                  CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1196435933ddSDimitry Andric   LoadSubCommand("remove",
1197435933ddSDimitry Andric                  CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1198435933ddSDimitry Andric   LoadSubCommand("replace", CommandObjectSP(
1199435933ddSDimitry Andric                                 new CommandObjectSettingsReplace(interpreter)));
1200435933ddSDimitry Andric   LoadSubCommand(
1201435933ddSDimitry Andric       "insert-before",
1202435933ddSDimitry Andric       CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1203435933ddSDimitry Andric   LoadSubCommand(
1204435933ddSDimitry Andric       "insert-after",
1205435933ddSDimitry Andric       CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1206435933ddSDimitry Andric   LoadSubCommand("append",
1207435933ddSDimitry Andric                  CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1208435933ddSDimitry Andric   LoadSubCommand("clear",
1209435933ddSDimitry Andric                  CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
1210*b5893f02SDimitry Andric   LoadSubCommand("write",
1211*b5893f02SDimitry Andric                  CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1212*b5893f02SDimitry Andric   LoadSubCommand("read",
1213*b5893f02SDimitry Andric                  CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1214ac7ddfbfSEd Maste }
1215ac7ddfbfSEd Maste 
12164bb0738eSEd Maste CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;
1217