@@ -320,6 +320,207 @@ class CommandObjectSettingsShow : public CommandObjectParsed {
320
320
}
321
321
};
322
322
323
+ // -------------------------------------------------------------------------
324
+ // CommandObjectSettingsWrite -- Write settings to file
325
+ // -------------------------------------------------------------------------
326
+
327
+ static constexpr OptionDefinition g_settings_write_options[] = {
328
+ // clang-format off
329
+ { LLDB_OPT_SET_ALL, true , " file" , ' f' , OptionParser::eRequiredArgument, nullptr , {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, " The file into which to write the settings." },
330
+ { LLDB_OPT_SET_ALL, false , " append" ,' a' , OptionParser::eNoArgument, nullptr , {}, 0 , eArgTypeNone, " Append to saved settings file if it exists." },
331
+ // clang-format on
332
+ };
333
+
334
+ class CommandObjectSettingsWrite : public CommandObjectParsed {
335
+ public:
336
+ CommandObjectSettingsWrite (CommandInterpreter &interpreter)
337
+ : CommandObjectParsed(
338
+ interpreter, " settings export" ,
339
+ " Write matching debugger settings and their "
340
+ " current values to a file that can be read in with "
341
+ " \" settings read\" . Defaults to writing all settings." ,
342
+ nullptr ),
343
+ m_options () {
344
+ CommandArgumentEntry arg1;
345
+ CommandArgumentData var_name_arg;
346
+
347
+ // Define the first (and only) variant of this arg.
348
+ var_name_arg.arg_type = eArgTypeSettingVariableName;
349
+ var_name_arg.arg_repetition = eArgRepeatOptional;
350
+
351
+ // There is only one variant this argument could be; put it into the
352
+ // argument entry.
353
+ arg1.push_back (var_name_arg);
354
+
355
+ // Push the data for the first argument into the m_arguments vector.
356
+ m_arguments.push_back (arg1);
357
+ }
358
+
359
+ ~CommandObjectSettingsWrite () override = default ;
360
+
361
+ Options *GetOptions () override { return &m_options; }
362
+
363
+ class CommandOptions : public Options {
364
+ public:
365
+ CommandOptions () : Options() {}
366
+
367
+ ~CommandOptions () override = default ;
368
+
369
+ Status SetOptionValue (uint32_t option_idx, llvm::StringRef option_arg,
370
+ ExecutionContext *execution_context) override {
371
+ Status error;
372
+ const int short_option = m_getopt_table[option_idx].val ;
373
+
374
+ switch (short_option) {
375
+ case ' f' :
376
+ m_filename.assign (option_arg);
377
+ break ;
378
+ case ' a' :
379
+ m_append = true ;
380
+ break ;
381
+ default :
382
+ error.SetErrorStringWithFormat (" unrecognized option '%c'" ,
383
+ short_option);
384
+ break ;
385
+ }
386
+
387
+ return error;
388
+ }
389
+
390
+ void OptionParsingStarting (ExecutionContext *execution_context) override {
391
+ m_filename.clear ();
392
+ m_append = false ;
393
+ }
394
+
395
+ llvm::ArrayRef<OptionDefinition> GetDefinitions () override {
396
+ return llvm::makeArrayRef (g_settings_write_options);
397
+ }
398
+
399
+ // Instance variables to hold the values for command options.
400
+ std::string m_filename;
401
+ bool m_append = false ;
402
+ };
403
+
404
+ protected:
405
+ bool DoExecute (Args &args, CommandReturnObject &result) override {
406
+ std::string path (FileSpec (m_options.m_filename , true ).GetPath ());
407
+ uint32_t options = File::OpenOptions::eOpenOptionWrite |
408
+ File::OpenOptions::eOpenOptionCanCreate;
409
+ if (m_options.m_append )
410
+ options |= File::OpenOptions::eOpenOptionAppend;
411
+ else
412
+ options |= File::OpenOptions::eOpenOptionTruncate;
413
+
414
+ StreamFile out_file (path.c_str (), options,
415
+ lldb::eFilePermissionsFileDefault);
416
+
417
+ if (!out_file.GetFile ().IsValid ()) {
418
+ result.AppendErrorWithFormat (" %s: unable to write to file" , path.c_str ());
419
+ result.SetStatus (eReturnStatusFailed);
420
+ return false ;
421
+ }
422
+
423
+ // Exporting should not be context sensitive.
424
+ ExecutionContext clean_ctx;
425
+
426
+ if (args.empty ()) {
427
+ m_interpreter.GetDebugger ().DumpAllPropertyValues (
428
+ &clean_ctx, out_file, OptionValue::eDumpGroupExport);
429
+ return result.Succeeded ();
430
+ }
431
+
432
+ for (const auto &arg : args) {
433
+ Status error (m_interpreter.GetDebugger ().DumpPropertyValue (
434
+ &clean_ctx, out_file, arg.ref , OptionValue::eDumpGroupExport));
435
+ if (!error.Success ()) {
436
+ result.AppendError (error.AsCString ());
437
+ result.SetStatus (eReturnStatusFailed);
438
+ }
439
+ }
440
+
441
+ return result.Succeeded ();
442
+ }
443
+
444
+ private:
445
+ CommandOptions m_options;
446
+ };
447
+
448
+ // -------------------------------------------------------------------------
449
+ // CommandObjectSettingsRead -- Read settings from file
450
+ // -------------------------------------------------------------------------
451
+
452
+ static constexpr OptionDefinition g_settings_read_options[] = {
453
+ // clang-format off
454
+ {LLDB_OPT_SET_ALL, true , " file" ,' f' , OptionParser::eRequiredArgument, nullptr , {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, " The file from which to read the breakpoints." },
455
+ // clang-format on
456
+ };
457
+
458
+ class CommandObjectSettingsRead : public CommandObjectParsed {
459
+ public:
460
+ CommandObjectSettingsRead (CommandInterpreter &interpreter)
461
+ : CommandObjectParsed(
462
+ interpreter, " settings read" ,
463
+ " Read settings previously saved to a file with \" settings write\" ." ,
464
+ nullptr ),
465
+ m_options () {}
466
+
467
+ ~CommandObjectSettingsRead () override = default ;
468
+
469
+ Options *GetOptions () override { return &m_options; }
470
+
471
+ class CommandOptions : public Options {
472
+ public:
473
+ CommandOptions () : Options() {}
474
+
475
+ ~CommandOptions () override = default ;
476
+
477
+ Status SetOptionValue (uint32_t option_idx, llvm::StringRef option_arg,
478
+ ExecutionContext *execution_context) override {
479
+ Status error;
480
+ const int short_option = m_getopt_table[option_idx].val ;
481
+
482
+ switch (short_option) {
483
+ case ' f' :
484
+ m_filename.assign (option_arg);
485
+ break ;
486
+ default :
487
+ error.SetErrorStringWithFormat (" unrecognized option '%c'" ,
488
+ short_option);
489
+ break ;
490
+ }
491
+
492
+ return error;
493
+ }
494
+
495
+ void OptionParsingStarting (ExecutionContext *execution_context) override {
496
+ m_filename.clear ();
497
+ }
498
+
499
+ llvm::ArrayRef<OptionDefinition> GetDefinitions () override {
500
+ return llvm::makeArrayRef (g_settings_read_options);
501
+ }
502
+
503
+ // Instance variables to hold the values for command options.
504
+ std::string m_filename;
505
+ };
506
+
507
+ protected:
508
+ bool DoExecute (Args &command, CommandReturnObject &result) override {
509
+ FileSpec file (m_options.m_filename , true );
510
+ ExecutionContext clean_ctx;
511
+ CommandInterpreterRunOptions options;
512
+ options.SetAddToHistory (false );
513
+ options.SetEchoCommands (false );
514
+ options.SetPrintResults (true );
515
+ options.SetStopOnError (false );
516
+ m_interpreter.HandleCommandsFromFile (file, &clean_ctx, options, result);
517
+ return result.Succeeded ();
518
+ }
519
+
520
+ private:
521
+ CommandOptions m_options;
522
+ };
523
+
323
524
// -------------------------------------------------------------------------
324
525
// CommandObjectSettingsList -- List settable variables
325
526
// -------------------------------------------------------------------------
@@ -1007,6 +1208,10 @@ CommandObjectMultiwordSettings::CommandObjectMultiwordSettings(
1007
1208
CommandObjectSP (new CommandObjectSettingsAppend (interpreter)));
1008
1209
LoadSubCommand (" clear" ,
1009
1210
CommandObjectSP (new CommandObjectSettingsClear (interpreter)));
1211
+ LoadSubCommand (" write" ,
1212
+ CommandObjectSP (new CommandObjectSettingsWrite (interpreter)));
1213
+ LoadSubCommand (" read" ,
1214
+ CommandObjectSP (new CommandObjectSettingsRead (interpreter)));
1010
1215
}
1011
1216
1012
1217
CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings () = default ;
0 commit comments