Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp
39587 views
1
//===-- CommandObjectSettings.cpp -----------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "CommandObjectSettings.h"
10
11
#include "llvm/ADT/StringRef.h"
12
13
#include "lldb/Host/OptionParser.h"
14
#include "lldb/Interpreter/CommandCompletions.h"
15
#include "lldb/Interpreter/CommandInterpreter.h"
16
#include "lldb/Interpreter/CommandOptionArgumentTable.h"
17
#include "lldb/Interpreter/CommandReturnObject.h"
18
#include "lldb/Interpreter/OptionValueProperties.h"
19
20
using namespace lldb;
21
using namespace lldb_private;
22
23
// CommandObjectSettingsSet
24
#define LLDB_OPTIONS_settings_set
25
#include "CommandOptions.inc"
26
27
class CommandObjectSettingsSet : public CommandObjectRaw {
28
public:
29
CommandObjectSettingsSet(CommandInterpreter &interpreter)
30
: CommandObjectRaw(interpreter, "settings set",
31
"Set the value of the specified debugger setting.") {
32
CommandArgumentEntry arg1;
33
CommandArgumentEntry arg2;
34
CommandArgumentData var_name_arg;
35
CommandArgumentData value_arg;
36
37
// Define the first (and only) variant of this arg.
38
var_name_arg.arg_type = eArgTypeSettingVariableName;
39
var_name_arg.arg_repetition = eArgRepeatPlain;
40
41
// There is only one variant this argument could be; put it into the
42
// argument entry.
43
arg1.push_back(var_name_arg);
44
45
// Define the first (and only) variant of this arg.
46
value_arg.arg_type = eArgTypeValue;
47
value_arg.arg_repetition = eArgRepeatPlain;
48
49
// There is only one variant this argument could be; put it into the
50
// argument entry.
51
arg2.push_back(value_arg);
52
53
// Push the data for the first argument into the m_arguments vector.
54
m_arguments.push_back(arg1);
55
m_arguments.push_back(arg2);
56
57
SetHelpLong(
58
"\nWhen setting a dictionary or array variable, you can set multiple entries \
59
at once by giving the values to the set command. For example:"
60
R"(
61
62
(lldb) settings set target.run-args value1 value2 value3
63
(lldb) settings set target.env-vars MYPATH=~/.:/usr/bin SOME_ENV_VAR=12345
64
65
(lldb) settings show target.run-args
66
[0]: 'value1'
67
[1]: 'value2'
68
[3]: 'value3'
69
(lldb) settings show target.env-vars
70
'MYPATH=~/.:/usr/bin'
71
'SOME_ENV_VAR=12345'
72
73
)"
74
"Warning: The 'set' command re-sets the entire array or dictionary. If you \
75
just want to add, remove or update individual values (or add something to \
76
the end), use one of the other settings sub-commands: append, replace, \
77
insert-before or insert-after.");
78
}
79
80
~CommandObjectSettingsSet() override = default;
81
82
// Overrides base class's behavior where WantsCompletion =
83
// !WantsRawCommandString.
84
bool WantsCompletion() override { return true; }
85
86
Options *GetOptions() override { return &m_options; }
87
88
class CommandOptions : public Options {
89
public:
90
CommandOptions() = default;
91
92
~CommandOptions() override = default;
93
94
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
95
ExecutionContext *execution_context) override {
96
Status error;
97
const int short_option = m_getopt_table[option_idx].val;
98
99
switch (short_option) {
100
case 'f':
101
m_force = true;
102
break;
103
case 'g':
104
m_global = true;
105
break;
106
case 'e':
107
m_exists = true;
108
break;
109
default:
110
llvm_unreachable("Unimplemented option");
111
}
112
113
return error;
114
}
115
116
void OptionParsingStarting(ExecutionContext *execution_context) override {
117
m_global = false;
118
m_force = false;
119
m_exists = false;
120
}
121
122
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
123
return llvm::ArrayRef(g_settings_set_options);
124
}
125
126
// Instance variables to hold the values for command options.
127
bool m_global = false;
128
bool m_force = false;
129
bool m_exists = false;
130
};
131
132
void
133
HandleArgumentCompletion(CompletionRequest &request,
134
OptionElementVector &opt_element_vector) override {
135
136
const size_t argc = request.GetParsedLine().GetArgumentCount();
137
const char *arg = nullptr;
138
size_t setting_var_idx;
139
for (setting_var_idx = 0; setting_var_idx < argc; ++setting_var_idx) {
140
arg = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
141
if (arg && arg[0] != '-')
142
break; // We found our setting variable name index
143
}
144
if (request.GetCursorIndex() == setting_var_idx) {
145
// Attempting to complete setting variable name
146
lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
147
GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
148
nullptr);
149
return;
150
}
151
arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex());
152
153
if (!arg)
154
return;
155
156
// Complete option name
157
if (arg[0] == '-')
158
return;
159
160
// Complete setting value
161
const char *setting_var_name =
162
request.GetParsedLine().GetArgumentAtIndex(setting_var_idx);
163
Status error;
164
lldb::OptionValueSP value_sp(
165
GetDebugger().GetPropertyValue(&m_exe_ctx, setting_var_name, error));
166
if (!value_sp)
167
return;
168
value_sp->AutoComplete(m_interpreter, request);
169
}
170
171
protected:
172
void DoExecute(llvm::StringRef command,
173
CommandReturnObject &result) override {
174
Args cmd_args(command);
175
176
// Process possible options.
177
if (!ParseOptions(cmd_args, result))
178
return;
179
180
const size_t min_argc = m_options.m_force ? 1 : 2;
181
const size_t argc = cmd_args.GetArgumentCount();
182
183
if ((argc < min_argc) && (!m_options.m_global)) {
184
result.AppendError("'settings set' takes more arguments");
185
return;
186
}
187
188
const char *var_name = cmd_args.GetArgumentAtIndex(0);
189
if ((var_name == nullptr) || (var_name[0] == '\0')) {
190
result.AppendError(
191
"'settings set' command requires a valid variable name");
192
return;
193
}
194
195
// A missing value corresponds to clearing the setting when "force" is
196
// specified.
197
if (argc == 1 && m_options.m_force) {
198
Status error(GetDebugger().SetPropertyValue(
199
&m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
200
if (error.Fail()) {
201
result.AppendError(error.AsCString());
202
}
203
return;
204
}
205
206
// Split the raw command into var_name and value pair.
207
llvm::StringRef var_value(command);
208
var_value = var_value.split(var_name).second.ltrim();
209
210
Status error;
211
if (m_options.m_global)
212
error = GetDebugger().SetPropertyValue(nullptr, eVarSetOperationAssign,
213
var_name, var_value);
214
215
if (error.Success()) {
216
// FIXME this is the same issue as the one in commands script import
217
// we could be setting target.load-script-from-symbol-file which would
218
// cause Python scripts to be loaded, which could run LLDB commands (e.g.
219
// settings set target.process.python-os-plugin-path) and cause a crash
220
// if we did not clear the command's exe_ctx first
221
ExecutionContext exe_ctx(m_exe_ctx);
222
m_exe_ctx.Clear();
223
error = GetDebugger().SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
224
var_name, var_value);
225
}
226
227
if (error.Fail() && !m_options.m_exists) {
228
result.AppendError(error.AsCString());
229
return;
230
}
231
232
result.SetStatus(eReturnStatusSuccessFinishResult);
233
}
234
235
private:
236
CommandOptions m_options;
237
};
238
239
// CommandObjectSettingsShow -- Show current values
240
241
class CommandObjectSettingsShow : public CommandObjectParsed {
242
public:
243
CommandObjectSettingsShow(CommandInterpreter &interpreter)
244
: CommandObjectParsed(interpreter, "settings show",
245
"Show matching debugger settings and their current "
246
"values. Defaults to showing all settings.",
247
nullptr) {
248
AddSimpleArgumentList(eArgTypeSettingVariableName, eArgRepeatOptional);
249
}
250
251
~CommandObjectSettingsShow() override = default;
252
253
protected:
254
void DoExecute(Args &args, CommandReturnObject &result) override {
255
result.SetStatus(eReturnStatusSuccessFinishResult);
256
257
if (!args.empty()) {
258
for (const auto &arg : args) {
259
Status error(GetDebugger().DumpPropertyValue(
260
&m_exe_ctx, result.GetOutputStream(), arg.ref(),
261
OptionValue::eDumpGroupValue));
262
if (error.Success()) {
263
result.GetOutputStream().EOL();
264
} else {
265
result.AppendError(error.AsCString());
266
}
267
}
268
} else {
269
GetDebugger().DumpAllPropertyValues(&m_exe_ctx, result.GetOutputStream(),
270
OptionValue::eDumpGroupValue);
271
}
272
}
273
};
274
275
// CommandObjectSettingsWrite -- Write settings to file
276
#define LLDB_OPTIONS_settings_write
277
#include "CommandOptions.inc"
278
279
class CommandObjectSettingsWrite : public CommandObjectParsed {
280
public:
281
CommandObjectSettingsWrite(CommandInterpreter &interpreter)
282
: CommandObjectParsed(
283
interpreter, "settings export",
284
"Write matching debugger settings and their "
285
"current values to a file that can be read in with "
286
"\"settings read\". Defaults to writing all settings.",
287
nullptr) {
288
AddSimpleArgumentList(eArgTypeSettingVariableName, eArgRepeatOptional);
289
}
290
291
~CommandObjectSettingsWrite() override = default;
292
293
Options *GetOptions() override { return &m_options; }
294
295
class CommandOptions : public Options {
296
public:
297
CommandOptions() = default;
298
299
~CommandOptions() override = default;
300
301
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
302
ExecutionContext *execution_context) override {
303
Status error;
304
const int short_option = m_getopt_table[option_idx].val;
305
306
switch (short_option) {
307
case 'f':
308
m_filename.assign(std::string(option_arg));
309
break;
310
case 'a':
311
m_append = true;
312
break;
313
default:
314
llvm_unreachable("Unimplemented option");
315
}
316
317
return error;
318
}
319
320
void OptionParsingStarting(ExecutionContext *execution_context) override {
321
m_filename.clear();
322
m_append = false;
323
}
324
325
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
326
return llvm::ArrayRef(g_settings_write_options);
327
}
328
329
// Instance variables to hold the values for command options.
330
std::string m_filename;
331
bool m_append = false;
332
};
333
334
protected:
335
void DoExecute(Args &args, CommandReturnObject &result) override {
336
FileSpec file_spec(m_options.m_filename);
337
FileSystem::Instance().Resolve(file_spec);
338
std::string path(file_spec.GetPath());
339
auto options = File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
340
if (m_options.m_append)
341
options |= File::eOpenOptionAppend;
342
else
343
options |= File::eOpenOptionTruncate;
344
345
StreamFile out_file(path.c_str(), options,
346
lldb::eFilePermissionsFileDefault);
347
348
if (!out_file.GetFile().IsValid()) {
349
result.AppendErrorWithFormat("%s: unable to write to file", path.c_str());
350
return;
351
}
352
353
// Exporting should not be context sensitive.
354
ExecutionContext clean_ctx;
355
356
if (args.empty()) {
357
GetDebugger().DumpAllPropertyValues(&clean_ctx, out_file,
358
OptionValue::eDumpGroupExport);
359
return;
360
}
361
362
for (const auto &arg : args) {
363
Status error(GetDebugger().DumpPropertyValue(
364
&clean_ctx, out_file, arg.ref(), OptionValue::eDumpGroupExport));
365
if (!error.Success()) {
366
result.AppendError(error.AsCString());
367
}
368
}
369
}
370
371
private:
372
CommandOptions m_options;
373
};
374
375
// CommandObjectSettingsRead -- Read settings from file
376
#define LLDB_OPTIONS_settings_read
377
#include "CommandOptions.inc"
378
379
class CommandObjectSettingsRead : public CommandObjectParsed {
380
public:
381
CommandObjectSettingsRead(CommandInterpreter &interpreter)
382
: CommandObjectParsed(
383
interpreter, "settings read",
384
"Read settings previously saved to a file with \"settings write\".",
385
nullptr) {}
386
387
~CommandObjectSettingsRead() override = default;
388
389
Options *GetOptions() override { return &m_options; }
390
391
class CommandOptions : public Options {
392
public:
393
CommandOptions() = default;
394
395
~CommandOptions() override = default;
396
397
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
398
ExecutionContext *execution_context) override {
399
Status error;
400
const int short_option = m_getopt_table[option_idx].val;
401
402
switch (short_option) {
403
case 'f':
404
m_filename.assign(std::string(option_arg));
405
break;
406
default:
407
llvm_unreachable("Unimplemented option");
408
}
409
410
return error;
411
}
412
413
void OptionParsingStarting(ExecutionContext *execution_context) override {
414
m_filename.clear();
415
}
416
417
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
418
return llvm::ArrayRef(g_settings_read_options);
419
}
420
421
// Instance variables to hold the values for command options.
422
std::string m_filename;
423
};
424
425
protected:
426
void DoExecute(Args &command, CommandReturnObject &result) override {
427
FileSpec file(m_options.m_filename);
428
FileSystem::Instance().Resolve(file);
429
CommandInterpreterRunOptions options;
430
options.SetAddToHistory(false);
431
options.SetEchoCommands(false);
432
options.SetPrintResults(true);
433
options.SetPrintErrors(true);
434
options.SetStopOnError(false);
435
m_interpreter.HandleCommandsFromFile(file, options, result);
436
}
437
438
private:
439
CommandOptions m_options;
440
};
441
442
// CommandObjectSettingsList -- List settable variables
443
444
class CommandObjectSettingsList : public CommandObjectParsed {
445
public:
446
CommandObjectSettingsList(CommandInterpreter &interpreter)
447
: CommandObjectParsed(interpreter, "settings list",
448
"List and describe matching debugger settings. "
449
"Defaults to all listing all settings.",
450
nullptr) {
451
CommandArgumentEntry arg;
452
CommandArgumentData var_name_arg;
453
CommandArgumentData prefix_name_arg;
454
455
// Define the first variant of this arg.
456
var_name_arg.arg_type = eArgTypeSettingVariableName;
457
var_name_arg.arg_repetition = eArgRepeatOptional;
458
459
// Define the second variant of this arg.
460
prefix_name_arg.arg_type = eArgTypeSettingPrefix;
461
prefix_name_arg.arg_repetition = eArgRepeatOptional;
462
463
arg.push_back(var_name_arg);
464
arg.push_back(prefix_name_arg);
465
466
// Push the data for the first argument into the m_arguments vector.
467
m_arguments.push_back(arg);
468
}
469
470
~CommandObjectSettingsList() override = default;
471
472
void
473
HandleArgumentCompletion(CompletionRequest &request,
474
OptionElementVector &opt_element_vector) override {
475
lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
476
GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
477
nullptr);
478
}
479
480
protected:
481
void DoExecute(Args &args, CommandReturnObject &result) override {
482
result.SetStatus(eReturnStatusSuccessFinishResult);
483
484
const size_t argc = args.GetArgumentCount();
485
if (argc > 0) {
486
const bool dump_qualified_name = true;
487
488
for (const Args::ArgEntry &arg : args) {
489
const char *property_path = arg.c_str();
490
491
const Property *property =
492
GetDebugger().GetValueProperties()->GetPropertyAtPath(
493
&m_exe_ctx, property_path);
494
495
if (property) {
496
property->DumpDescription(m_interpreter, result.GetOutputStream(), 0,
497
dump_qualified_name);
498
} else {
499
result.AppendErrorWithFormat("invalid property path '%s'",
500
property_path);
501
}
502
}
503
} else {
504
GetDebugger().DumpAllDescriptions(m_interpreter,
505
result.GetOutputStream());
506
}
507
}
508
};
509
510
// CommandObjectSettingsRemove
511
512
class CommandObjectSettingsRemove : public CommandObjectRaw {
513
public:
514
CommandObjectSettingsRemove(CommandInterpreter &interpreter)
515
: CommandObjectRaw(interpreter, "settings remove",
516
"Remove a value from a setting, specified by array "
517
"index or dictionary key.") {
518
CommandArgumentEntry arg1;
519
CommandArgumentEntry arg2;
520
CommandArgumentData var_name_arg;
521
CommandArgumentData index_arg;
522
CommandArgumentData key_arg;
523
524
// Define the first (and only) variant of this arg.
525
var_name_arg.arg_type = eArgTypeSettingVariableName;
526
var_name_arg.arg_repetition = eArgRepeatPlain;
527
528
// There is only one variant this argument could be; put it into the
529
// argument entry.
530
arg1.push_back(var_name_arg);
531
532
// Define the first variant of this arg.
533
index_arg.arg_type = eArgTypeSettingIndex;
534
index_arg.arg_repetition = eArgRepeatPlain;
535
536
// Define the second variant of this arg.
537
key_arg.arg_type = eArgTypeSettingKey;
538
key_arg.arg_repetition = eArgRepeatPlain;
539
540
// Push both variants into this arg
541
arg2.push_back(index_arg);
542
arg2.push_back(key_arg);
543
544
// Push the data for the first argument into the m_arguments vector.
545
m_arguments.push_back(arg1);
546
m_arguments.push_back(arg2);
547
}
548
549
~CommandObjectSettingsRemove() override = default;
550
551
bool WantsCompletion() override { return true; }
552
553
void
554
HandleArgumentCompletion(CompletionRequest &request,
555
OptionElementVector &opt_element_vector) override {
556
if (request.GetCursorIndex() < 2)
557
lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
558
GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
559
nullptr);
560
}
561
562
protected:
563
void DoExecute(llvm::StringRef command,
564
CommandReturnObject &result) override {
565
result.SetStatus(eReturnStatusSuccessFinishNoResult);
566
567
Args cmd_args(command);
568
569
// Process possible options.
570
if (!ParseOptions(cmd_args, result))
571
return;
572
573
const size_t argc = cmd_args.GetArgumentCount();
574
if (argc == 0) {
575
result.AppendError("'settings remove' takes an array or dictionary item, "
576
"or an array followed by one or more indexes, or a "
577
"dictionary followed by one or more key names to "
578
"remove");
579
return;
580
}
581
582
const char *var_name = cmd_args.GetArgumentAtIndex(0);
583
if ((var_name == nullptr) || (var_name[0] == '\0')) {
584
result.AppendError(
585
"'settings remove' command requires a valid variable name");
586
return;
587
}
588
589
// Split the raw command into var_name and value pair.
590
llvm::StringRef var_value(command);
591
var_value = var_value.split(var_name).second.trim();
592
593
Status error(GetDebugger().SetPropertyValue(
594
&m_exe_ctx, eVarSetOperationRemove, var_name, var_value));
595
if (error.Fail()) {
596
result.AppendError(error.AsCString());
597
}
598
}
599
};
600
601
// CommandObjectSettingsReplace
602
603
class CommandObjectSettingsReplace : public CommandObjectRaw {
604
public:
605
CommandObjectSettingsReplace(CommandInterpreter &interpreter)
606
: CommandObjectRaw(interpreter, "settings replace",
607
"Replace the debugger setting value specified by "
608
"array index or dictionary key.") {
609
CommandArgumentEntry arg1;
610
CommandArgumentEntry arg2;
611
CommandArgumentEntry arg3;
612
CommandArgumentData var_name_arg;
613
CommandArgumentData index_arg;
614
CommandArgumentData key_arg;
615
CommandArgumentData value_arg;
616
617
// Define the first (and only) variant of this arg.
618
var_name_arg.arg_type = eArgTypeSettingVariableName;
619
var_name_arg.arg_repetition = eArgRepeatPlain;
620
621
// There is only one variant this argument could be; put it into the
622
// argument entry.
623
arg1.push_back(var_name_arg);
624
625
// Define the first (variant of this arg.
626
index_arg.arg_type = eArgTypeSettingIndex;
627
index_arg.arg_repetition = eArgRepeatPlain;
628
629
// Define the second (variant of this arg.
630
key_arg.arg_type = eArgTypeSettingKey;
631
key_arg.arg_repetition = eArgRepeatPlain;
632
633
// Put both variants into this arg
634
arg2.push_back(index_arg);
635
arg2.push_back(key_arg);
636
637
// Define the first (and only) variant of this arg.
638
value_arg.arg_type = eArgTypeValue;
639
value_arg.arg_repetition = eArgRepeatPlain;
640
641
// There is only one variant this argument could be; put it into the
642
// argument entry.
643
arg3.push_back(value_arg);
644
645
// Push the data for the first argument into the m_arguments vector.
646
m_arguments.push_back(arg1);
647
m_arguments.push_back(arg2);
648
m_arguments.push_back(arg3);
649
}
650
651
~CommandObjectSettingsReplace() override = default;
652
653
// Overrides base class's behavior where WantsCompletion =
654
// !WantsRawCommandString.
655
bool WantsCompletion() override { return true; }
656
657
void
658
HandleArgumentCompletion(CompletionRequest &request,
659
OptionElementVector &opt_element_vector) override {
660
// Attempting to complete variable name
661
if (request.GetCursorIndex() < 2)
662
lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
663
GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
664
nullptr);
665
}
666
667
protected:
668
void DoExecute(llvm::StringRef command,
669
CommandReturnObject &result) override {
670
result.SetStatus(eReturnStatusSuccessFinishNoResult);
671
672
Args cmd_args(command);
673
const char *var_name = cmd_args.GetArgumentAtIndex(0);
674
if ((var_name == nullptr) || (var_name[0] == '\0')) {
675
result.AppendError("'settings replace' command requires a valid variable "
676
"name; No value supplied");
677
return;
678
}
679
680
// Split the raw command into var_name, index_value, and value triple.
681
llvm::StringRef var_value(command);
682
var_value = var_value.split(var_name).second.trim();
683
684
Status error(GetDebugger().SetPropertyValue(
685
&m_exe_ctx, eVarSetOperationReplace, var_name, var_value));
686
if (error.Fail()) {
687
result.AppendError(error.AsCString());
688
} else {
689
result.SetStatus(eReturnStatusSuccessFinishNoResult);
690
}
691
}
692
};
693
694
// CommandObjectSettingsInsertBefore
695
696
class CommandObjectSettingsInsertBefore : public CommandObjectRaw {
697
public:
698
CommandObjectSettingsInsertBefore(CommandInterpreter &interpreter)
699
: CommandObjectRaw(interpreter, "settings insert-before",
700
"Insert one or more values into an debugger array "
701
"setting immediately before the specified element "
702
"index.") {
703
CommandArgumentEntry arg1;
704
CommandArgumentEntry arg2;
705
CommandArgumentEntry arg3;
706
CommandArgumentData var_name_arg;
707
CommandArgumentData index_arg;
708
CommandArgumentData value_arg;
709
710
// Define the first (and only) variant of this arg.
711
var_name_arg.arg_type = eArgTypeSettingVariableName;
712
var_name_arg.arg_repetition = eArgRepeatPlain;
713
714
// There is only one variant this argument could be; put it into the
715
// argument entry.
716
arg1.push_back(var_name_arg);
717
718
// Define the first (variant of this arg.
719
index_arg.arg_type = eArgTypeSettingIndex;
720
index_arg.arg_repetition = eArgRepeatPlain;
721
722
// There is only one variant this argument could be; put it into the
723
// argument entry.
724
arg2.push_back(index_arg);
725
726
// Define the first (and only) variant of this arg.
727
value_arg.arg_type = eArgTypeValue;
728
value_arg.arg_repetition = eArgRepeatPlain;
729
730
// There is only one variant this argument could be; put it into the
731
// argument entry.
732
arg3.push_back(value_arg);
733
734
// Push the data for the first argument into the m_arguments vector.
735
m_arguments.push_back(arg1);
736
m_arguments.push_back(arg2);
737
m_arguments.push_back(arg3);
738
}
739
740
~CommandObjectSettingsInsertBefore() override = default;
741
742
// Overrides base class's behavior where WantsCompletion =
743
// !WantsRawCommandString.
744
bool WantsCompletion() override { return true; }
745
746
void
747
HandleArgumentCompletion(CompletionRequest &request,
748
OptionElementVector &opt_element_vector) override {
749
// Attempting to complete variable name
750
if (request.GetCursorIndex() < 2)
751
lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
752
GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
753
nullptr);
754
}
755
756
protected:
757
void DoExecute(llvm::StringRef command,
758
CommandReturnObject &result) override {
759
result.SetStatus(eReturnStatusSuccessFinishNoResult);
760
761
Args cmd_args(command);
762
const size_t argc = cmd_args.GetArgumentCount();
763
764
if (argc < 3) {
765
result.AppendError("'settings insert-before' takes more arguments");
766
return;
767
}
768
769
const char *var_name = cmd_args.GetArgumentAtIndex(0);
770
if ((var_name == nullptr) || (var_name[0] == '\0')) {
771
result.AppendError("'settings insert-before' command requires a valid "
772
"variable name; No value supplied");
773
return;
774
}
775
776
// Split the raw command into var_name, index_value, and value triple.
777
llvm::StringRef var_value(command);
778
var_value = var_value.split(var_name).second.trim();
779
780
Status error(GetDebugger().SetPropertyValue(
781
&m_exe_ctx, eVarSetOperationInsertBefore, var_name, var_value));
782
if (error.Fail()) {
783
result.AppendError(error.AsCString());
784
}
785
}
786
};
787
788
// CommandObjectSettingInsertAfter
789
790
class CommandObjectSettingsInsertAfter : public CommandObjectRaw {
791
public:
792
CommandObjectSettingsInsertAfter(CommandInterpreter &interpreter)
793
: CommandObjectRaw(interpreter, "settings insert-after",
794
"Insert one or more values into a debugger array "
795
"settings after the specified element index.") {
796
CommandArgumentEntry arg1;
797
CommandArgumentEntry arg2;
798
CommandArgumentEntry arg3;
799
CommandArgumentData var_name_arg;
800
CommandArgumentData index_arg;
801
CommandArgumentData value_arg;
802
803
// Define the first (and only) variant of this arg.
804
var_name_arg.arg_type = eArgTypeSettingVariableName;
805
var_name_arg.arg_repetition = eArgRepeatPlain;
806
807
// There is only one variant this argument could be; put it into the
808
// argument entry.
809
arg1.push_back(var_name_arg);
810
811
// Define the first (variant of this arg.
812
index_arg.arg_type = eArgTypeSettingIndex;
813
index_arg.arg_repetition = eArgRepeatPlain;
814
815
// There is only one variant this argument could be; put it into the
816
// argument entry.
817
arg2.push_back(index_arg);
818
819
// Define the first (and only) variant of this arg.
820
value_arg.arg_type = eArgTypeValue;
821
value_arg.arg_repetition = eArgRepeatPlain;
822
823
// There is only one variant this argument could be; put it into the
824
// argument entry.
825
arg3.push_back(value_arg);
826
827
// Push the data for the first argument into the m_arguments vector.
828
m_arguments.push_back(arg1);
829
m_arguments.push_back(arg2);
830
m_arguments.push_back(arg3);
831
}
832
833
~CommandObjectSettingsInsertAfter() override = default;
834
835
// Overrides base class's behavior where WantsCompletion =
836
// !WantsRawCommandString.
837
bool WantsCompletion() override { return true; }
838
839
void
840
HandleArgumentCompletion(CompletionRequest &request,
841
OptionElementVector &opt_element_vector) override {
842
// Attempting to complete variable name
843
if (request.GetCursorIndex() < 2)
844
lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
845
GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
846
nullptr);
847
}
848
849
protected:
850
void DoExecute(llvm::StringRef command,
851
CommandReturnObject &result) override {
852
result.SetStatus(eReturnStatusSuccessFinishNoResult);
853
854
Args cmd_args(command);
855
const size_t argc = cmd_args.GetArgumentCount();
856
857
if (argc < 3) {
858
result.AppendError("'settings insert-after' takes more arguments");
859
return;
860
}
861
862
const char *var_name = cmd_args.GetArgumentAtIndex(0);
863
if ((var_name == nullptr) || (var_name[0] == '\0')) {
864
result.AppendError("'settings insert-after' command requires a valid "
865
"variable name; No value supplied");
866
return;
867
}
868
869
// Split the raw command into var_name, index_value, and value triple.
870
llvm::StringRef var_value(command);
871
var_value = var_value.split(var_name).second.trim();
872
873
Status error(GetDebugger().SetPropertyValue(
874
&m_exe_ctx, eVarSetOperationInsertAfter, var_name, var_value));
875
if (error.Fail()) {
876
result.AppendError(error.AsCString());
877
}
878
}
879
};
880
881
// CommandObjectSettingsAppend
882
883
class CommandObjectSettingsAppend : public CommandObjectRaw {
884
public:
885
CommandObjectSettingsAppend(CommandInterpreter &interpreter)
886
: CommandObjectRaw(interpreter, "settings append",
887
"Append one or more values to a debugger array, "
888
"dictionary, or string setting.") {
889
CommandArgumentEntry arg1;
890
CommandArgumentEntry arg2;
891
CommandArgumentData var_name_arg;
892
CommandArgumentData value_arg;
893
894
// Define the first (and only) variant of this arg.
895
var_name_arg.arg_type = eArgTypeSettingVariableName;
896
var_name_arg.arg_repetition = eArgRepeatPlain;
897
898
// There is only one variant this argument could be; put it into the
899
// argument entry.
900
arg1.push_back(var_name_arg);
901
902
// Define the first (and only) variant of this arg.
903
value_arg.arg_type = eArgTypeValue;
904
value_arg.arg_repetition = eArgRepeatPlain;
905
906
// There is only one variant this argument could be; put it into the
907
// argument entry.
908
arg2.push_back(value_arg);
909
910
// Push the data for the first argument into the m_arguments vector.
911
m_arguments.push_back(arg1);
912
m_arguments.push_back(arg2);
913
}
914
915
~CommandObjectSettingsAppend() override = default;
916
917
// Overrides base class's behavior where WantsCompletion =
918
// !WantsRawCommandString.
919
bool WantsCompletion() override { return true; }
920
921
void
922
HandleArgumentCompletion(CompletionRequest &request,
923
OptionElementVector &opt_element_vector) override {
924
// Attempting to complete variable name
925
if (request.GetCursorIndex() < 2)
926
lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
927
GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
928
nullptr);
929
}
930
931
protected:
932
void DoExecute(llvm::StringRef command,
933
CommandReturnObject &result) override {
934
result.SetStatus(eReturnStatusSuccessFinishNoResult);
935
Args cmd_args(command);
936
const size_t argc = cmd_args.GetArgumentCount();
937
938
if (argc < 2) {
939
result.AppendError("'settings append' takes more arguments");
940
return;
941
}
942
943
const char *var_name = cmd_args.GetArgumentAtIndex(0);
944
if ((var_name == nullptr) || (var_name[0] == '\0')) {
945
result.AppendError("'settings append' command requires a valid variable "
946
"name; No value supplied");
947
return;
948
}
949
950
// Do not perform cmd_args.Shift() since StringRef is manipulating the raw
951
// character string later on.
952
953
// Split the raw command into var_name and value pair.
954
llvm::StringRef var_value(command);
955
var_value = var_value.split(var_name).second.trim();
956
957
Status error(GetDebugger().SetPropertyValue(
958
&m_exe_ctx, eVarSetOperationAppend, var_name, var_value));
959
if (error.Fail()) {
960
result.AppendError(error.AsCString());
961
}
962
}
963
};
964
965
// CommandObjectSettingsClear
966
#define LLDB_OPTIONS_settings_clear
967
#include "CommandOptions.inc"
968
969
class CommandObjectSettingsClear : public CommandObjectParsed {
970
public:
971
CommandObjectSettingsClear(CommandInterpreter &interpreter)
972
: CommandObjectParsed(
973
interpreter, "settings clear",
974
"Clear a debugger setting array, dictionary, or string. "
975
"If '-a' option is specified, it clears all settings.", nullptr) {
976
AddSimpleArgumentList(eArgTypeSettingVariableName);
977
}
978
979
~CommandObjectSettingsClear() override = default;
980
981
void
982
HandleArgumentCompletion(CompletionRequest &request,
983
OptionElementVector &opt_element_vector) override {
984
// Attempting to complete variable name
985
if (request.GetCursorIndex() < 2)
986
lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
987
GetCommandInterpreter(), lldb::eSettingsNameCompletion, request,
988
nullptr);
989
}
990
991
Options *GetOptions() override { return &m_options; }
992
993
class CommandOptions : public Options {
994
public:
995
CommandOptions() = default;
996
997
~CommandOptions() override = default;
998
999
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1000
ExecutionContext *execution_context) override {
1001
const int short_option = m_getopt_table[option_idx].val;
1002
switch (short_option) {
1003
case 'a':
1004
m_clear_all = true;
1005
break;
1006
default:
1007
llvm_unreachable("Unimplemented option");
1008
}
1009
return Status();
1010
}
1011
1012
void OptionParsingStarting(ExecutionContext *execution_context) override {
1013
m_clear_all = false;
1014
}
1015
1016
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1017
return llvm::ArrayRef(g_settings_clear_options);
1018
}
1019
1020
bool m_clear_all = false;
1021
};
1022
1023
protected:
1024
void DoExecute(Args &command, CommandReturnObject &result) override {
1025
result.SetStatus(eReturnStatusSuccessFinishNoResult);
1026
const size_t argc = command.GetArgumentCount();
1027
1028
if (m_options.m_clear_all) {
1029
if (argc != 0) {
1030
result.AppendError("'settings clear --all' doesn't take any arguments");
1031
return;
1032
}
1033
GetDebugger().GetValueProperties()->Clear();
1034
return;
1035
}
1036
1037
if (argc != 1) {
1038
result.AppendError("'settings clear' takes exactly one argument");
1039
return;
1040
}
1041
1042
const char *var_name = command.GetArgumentAtIndex(0);
1043
if ((var_name == nullptr) || (var_name[0] == '\0')) {
1044
result.AppendError("'settings clear' command requires a valid variable "
1045
"name; No value supplied");
1046
return;
1047
}
1048
1049
Status error(GetDebugger().SetPropertyValue(
1050
&m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef()));
1051
if (error.Fail()) {
1052
result.AppendError(error.AsCString());
1053
}
1054
}
1055
1056
private:
1057
CommandOptions m_options;
1058
};
1059
1060
// CommandObjectMultiwordSettings
1061
1062
CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1063
CommandInterpreter &interpreter)
1064
: CommandObjectMultiword(interpreter, "settings",
1065
"Commands for managing LLDB settings.",
1066
"settings <subcommand> [<command-options>]") {
1067
LoadSubCommand("set",
1068
CommandObjectSP(new CommandObjectSettingsSet(interpreter)));
1069
LoadSubCommand("show",
1070
CommandObjectSP(new CommandObjectSettingsShow(interpreter)));
1071
LoadSubCommand("list",
1072
CommandObjectSP(new CommandObjectSettingsList(interpreter)));
1073
LoadSubCommand("remove",
1074
CommandObjectSP(new CommandObjectSettingsRemove(interpreter)));
1075
LoadSubCommand("replace", CommandObjectSP(
1076
new CommandObjectSettingsReplace(interpreter)));
1077
LoadSubCommand(
1078
"insert-before",
1079
CommandObjectSP(new CommandObjectSettingsInsertBefore(interpreter)));
1080
LoadSubCommand(
1081
"insert-after",
1082
CommandObjectSP(new CommandObjectSettingsInsertAfter(interpreter)));
1083
LoadSubCommand("append",
1084
CommandObjectSP(new CommandObjectSettingsAppend(interpreter)));
1085
LoadSubCommand("clear",
1086
CommandObjectSP(new CommandObjectSettingsClear(interpreter)));
1087
LoadSubCommand("write",
1088
CommandObjectSP(new CommandObjectSettingsWrite(interpreter)));
1089
LoadSubCommand("read",
1090
CommandObjectSP(new CommandObjectSettingsRead(interpreter)));
1091
}
1092
1093
CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default;
1094
1095