1e3b55780SDimitry Andric //===-- CommandObjectDiagnostics.cpp --------------------------------------===//
2e3b55780SDimitry Andric //
3e3b55780SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e3b55780SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e3b55780SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e3b55780SDimitry Andric //
7e3b55780SDimitry Andric //===----------------------------------------------------------------------===//
8e3b55780SDimitry Andric
9e3b55780SDimitry Andric #include "CommandObjectDiagnostics.h"
10e3b55780SDimitry Andric #include "lldb/Host/OptionParser.h"
11e3b55780SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h"
12e3b55780SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
13e3b55780SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
14e3b55780SDimitry Andric #include "lldb/Interpreter/OptionValueEnumeration.h"
15e3b55780SDimitry Andric #include "lldb/Interpreter/OptionValueUInt64.h"
16e3b55780SDimitry Andric #include "lldb/Interpreter/Options.h"
17e3b55780SDimitry Andric #include "lldb/Utility/Diagnostics.h"
18e3b55780SDimitry Andric
19e3b55780SDimitry Andric using namespace lldb;
20e3b55780SDimitry Andric using namespace lldb_private;
21e3b55780SDimitry Andric
22e3b55780SDimitry Andric #define LLDB_OPTIONS_diagnostics_dump
23e3b55780SDimitry Andric #include "CommandOptions.inc"
24e3b55780SDimitry Andric
25e3b55780SDimitry Andric class CommandObjectDiagnosticsDump : public CommandObjectParsed {
26e3b55780SDimitry Andric public:
27e3b55780SDimitry Andric // Constructors and Destructors
CommandObjectDiagnosticsDump(CommandInterpreter & interpreter)28e3b55780SDimitry Andric CommandObjectDiagnosticsDump(CommandInterpreter &interpreter)
29e3b55780SDimitry Andric : CommandObjectParsed(interpreter, "diagnostics dump",
30e3b55780SDimitry Andric "Dump diagnostics to disk", nullptr) {}
31e3b55780SDimitry Andric
32e3b55780SDimitry Andric ~CommandObjectDiagnosticsDump() override = default;
33e3b55780SDimitry Andric
34e3b55780SDimitry Andric class CommandOptions : public Options {
35e3b55780SDimitry Andric public:
36e3b55780SDimitry Andric CommandOptions() = default;
37e3b55780SDimitry Andric
38e3b55780SDimitry Andric ~CommandOptions() override = default;
39e3b55780SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)40e3b55780SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
41e3b55780SDimitry Andric ExecutionContext *execution_context) override {
42e3b55780SDimitry Andric Status error;
43e3b55780SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
44e3b55780SDimitry Andric
45e3b55780SDimitry Andric switch (short_option) {
46e3b55780SDimitry Andric case 'd':
47e3b55780SDimitry Andric directory.SetDirectory(option_arg);
48e3b55780SDimitry Andric break;
49e3b55780SDimitry Andric default:
50e3b55780SDimitry Andric llvm_unreachable("Unimplemented option");
51e3b55780SDimitry Andric }
52e3b55780SDimitry Andric return error;
53e3b55780SDimitry Andric }
54e3b55780SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)55e3b55780SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
56e3b55780SDimitry Andric directory.Clear();
57e3b55780SDimitry Andric }
58e3b55780SDimitry Andric
GetDefinitions()59e3b55780SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
60e3b55780SDimitry Andric return llvm::ArrayRef(g_diagnostics_dump_options);
61e3b55780SDimitry Andric }
62e3b55780SDimitry Andric
63e3b55780SDimitry Andric FileSpec directory;
64e3b55780SDimitry Andric };
65e3b55780SDimitry Andric
GetOptions()66e3b55780SDimitry Andric Options *GetOptions() override { return &m_options; }
67e3b55780SDimitry Andric
68e3b55780SDimitry Andric protected:
GetDirectory()69e3b55780SDimitry Andric llvm::Expected<FileSpec> GetDirectory() {
70e3b55780SDimitry Andric if (m_options.directory) {
71e3b55780SDimitry Andric auto ec =
72e3b55780SDimitry Andric llvm::sys::fs::create_directories(m_options.directory.GetPath());
73e3b55780SDimitry Andric if (ec)
74e3b55780SDimitry Andric return llvm::errorCodeToError(ec);
75e3b55780SDimitry Andric return m_options.directory;
76e3b55780SDimitry Andric }
77e3b55780SDimitry Andric return Diagnostics::CreateUniqueDirectory();
78e3b55780SDimitry Andric }
79e3b55780SDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)80b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
81e3b55780SDimitry Andric llvm::Expected<FileSpec> directory = GetDirectory();
82e3b55780SDimitry Andric
83e3b55780SDimitry Andric if (!directory) {
84e3b55780SDimitry Andric result.AppendError(llvm::toString(directory.takeError()));
85b1c73532SDimitry Andric return;
86e3b55780SDimitry Andric }
87e3b55780SDimitry Andric
88e3b55780SDimitry Andric llvm::Error error = Diagnostics::Instance().Create(*directory);
89e3b55780SDimitry Andric if (error) {
90e3b55780SDimitry Andric result.AppendErrorWithFormat("failed to write diagnostics to %s",
91e3b55780SDimitry Andric directory->GetPath().c_str());
92e3b55780SDimitry Andric result.AppendError(llvm::toString(std::move(error)));
93b1c73532SDimitry Andric return;
94e3b55780SDimitry Andric }
95e3b55780SDimitry Andric
96e3b55780SDimitry Andric result.GetOutputStream() << "diagnostics written to " << *directory << '\n';
97e3b55780SDimitry Andric
98e3b55780SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
99b1c73532SDimitry Andric return;
100e3b55780SDimitry Andric }
101e3b55780SDimitry Andric
102e3b55780SDimitry Andric CommandOptions m_options;
103e3b55780SDimitry Andric };
104e3b55780SDimitry Andric
CommandObjectDiagnostics(CommandInterpreter & interpreter)105e3b55780SDimitry Andric CommandObjectDiagnostics::CommandObjectDiagnostics(
106e3b55780SDimitry Andric CommandInterpreter &interpreter)
107e3b55780SDimitry Andric : CommandObjectMultiword(interpreter, "diagnostics",
108e3b55780SDimitry Andric "Commands controlling LLDB diagnostics.",
109e3b55780SDimitry Andric "diagnostics <subcommand> [<command-options>]") {
110e3b55780SDimitry Andric LoadSubCommand(
111e3b55780SDimitry Andric "dump", CommandObjectSP(new CommandObjectDiagnosticsDump(interpreter)));
112e3b55780SDimitry Andric }
113e3b55780SDimitry Andric
114e3b55780SDimitry Andric CommandObjectDiagnostics::~CommandObjectDiagnostics() = default;
115