19e046f02SJonas Devlieghere //===-- CommandObjectReproducer.cpp -----------------------------*- C++ -*-===//
29e046f02SJonas Devlieghere //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69e046f02SJonas Devlieghere //
79e046f02SJonas Devlieghere //===----------------------------------------------------------------------===//
89e046f02SJonas Devlieghere 
99e046f02SJonas Devlieghere #include "CommandObjectReproducer.h"
109e046f02SJonas Devlieghere 
119e046f02SJonas Devlieghere #include "lldb/Utility/Reproducer.h"
129e046f02SJonas Devlieghere 
13df14b942SJonas Devlieghere #include "lldb/Interpreter/CommandInterpreter.h"
149e046f02SJonas Devlieghere #include "lldb/Interpreter/CommandReturnObject.h"
159e046f02SJonas Devlieghere #include "lldb/Interpreter/OptionArgParser.h"
169e046f02SJonas Devlieghere #include "lldb/Interpreter/OptionGroupBoolean.h"
179e046f02SJonas Devlieghere 
189e046f02SJonas Devlieghere using namespace lldb;
199e046f02SJonas Devlieghere using namespace lldb_private;
209e046f02SJonas Devlieghere 
219e046f02SJonas Devlieghere class CommandObjectReproducerGenerate : public CommandObjectParsed {
229e046f02SJonas Devlieghere public:
239e046f02SJonas Devlieghere   CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
249e046f02SJonas Devlieghere       : CommandObjectParsed(interpreter, "reproducer generate",
259e046f02SJonas Devlieghere                             "Generate reproducer on disk.", nullptr) {}
269e046f02SJonas Devlieghere 
279e046f02SJonas Devlieghere   ~CommandObjectReproducerGenerate() override = default;
289e046f02SJonas Devlieghere 
299e046f02SJonas Devlieghere protected:
309e046f02SJonas Devlieghere   bool DoExecute(Args &command, CommandReturnObject &result) override {
319e046f02SJonas Devlieghere     if (!command.empty()) {
329e046f02SJonas Devlieghere       result.AppendErrorWithFormat("'%s' takes no arguments",
339e046f02SJonas Devlieghere                                    m_cmd_name.c_str());
349e046f02SJonas Devlieghere       return false;
359e046f02SJonas Devlieghere     }
369e046f02SJonas Devlieghere 
379e046f02SJonas Devlieghere     auto &r = repro::Reproducer::Instance();
389e046f02SJonas Devlieghere     if (auto generator = r.GetGenerator()) {
399e046f02SJonas Devlieghere       generator->Keep();
40*2dca6538SJonas Devlieghere     } else if (r.GetLoader()) {
41*2dca6538SJonas Devlieghere       // Make this operation a NOP in replay mode.
42*2dca6538SJonas Devlieghere       result.SetStatus(eReturnStatusSuccessFinishNoResult);
43*2dca6538SJonas Devlieghere       return result.Succeeded();
449e046f02SJonas Devlieghere     } else {
459e046f02SJonas Devlieghere       result.AppendErrorWithFormat("Unable to get the reproducer generator");
46*2dca6538SJonas Devlieghere       result.SetStatus(eReturnStatusFailed);
479e046f02SJonas Devlieghere       return false;
489e046f02SJonas Devlieghere     }
499e046f02SJonas Devlieghere 
509e046f02SJonas Devlieghere     result.GetOutputStream()
519e046f02SJonas Devlieghere         << "Reproducer written to '" << r.GetReproducerPath() << "'\n";
529e046f02SJonas Devlieghere 
539e046f02SJonas Devlieghere     result.SetStatus(eReturnStatusSuccessFinishResult);
549e046f02SJonas Devlieghere     return result.Succeeded();
559e046f02SJonas Devlieghere   }
569e046f02SJonas Devlieghere };
579e046f02SJonas Devlieghere 
5815eacd74SJonas Devlieghere class CommandObjectReproducerStatus : public CommandObjectParsed {
599e046f02SJonas Devlieghere public:
6015eacd74SJonas Devlieghere   CommandObjectReproducerStatus(CommandInterpreter &interpreter)
6115eacd74SJonas Devlieghere       : CommandObjectParsed(interpreter, "reproducer status",
6215eacd74SJonas Devlieghere                             "Show the current reproducer status.", nullptr) {}
639e046f02SJonas Devlieghere 
6415eacd74SJonas Devlieghere   ~CommandObjectReproducerStatus() override = default;
659e046f02SJonas Devlieghere 
669e046f02SJonas Devlieghere protected:
679e046f02SJonas Devlieghere   bool DoExecute(Args &command, CommandReturnObject &result) override {
6815eacd74SJonas Devlieghere     if (!command.empty()) {
6915eacd74SJonas Devlieghere       result.AppendErrorWithFormat("'%s' takes no arguments",
709e046f02SJonas Devlieghere                                    m_cmd_name.c_str());
719e046f02SJonas Devlieghere       return false;
729e046f02SJonas Devlieghere     }
739e046f02SJonas Devlieghere 
749e046f02SJonas Devlieghere     auto &r = repro::Reproducer::Instance();
7552f8f343SZachary Turner     if (r.GetGenerator()) {
7615eacd74SJonas Devlieghere       result.GetOutputStream() << "Reproducer is in capture mode.\n";
7752f8f343SZachary Turner     } else if (r.GetLoader()) {
7815eacd74SJonas Devlieghere       result.GetOutputStream() << "Reproducer is in replay mode.\n";
7915eacd74SJonas Devlieghere     } else {
8015eacd74SJonas Devlieghere       result.GetOutputStream() << "Reproducer is off.\n";
819e046f02SJonas Devlieghere     }
829e046f02SJonas Devlieghere 
8315eacd74SJonas Devlieghere     result.SetStatus(eReturnStatusSuccessFinishResult);
849e046f02SJonas Devlieghere     return result.Succeeded();
859e046f02SJonas Devlieghere   }
869e046f02SJonas Devlieghere };
879e046f02SJonas Devlieghere 
889e046f02SJonas Devlieghere CommandObjectReproducer::CommandObjectReproducer(
899e046f02SJonas Devlieghere     CommandInterpreter &interpreter)
909e046f02SJonas Devlieghere     : CommandObjectMultiword(interpreter, "reproducer",
919e046f02SJonas Devlieghere                              "Commands controlling LLDB reproducers.",
929e046f02SJonas Devlieghere                              "log <subcommand> [<command-options>]") {
939e046f02SJonas Devlieghere   LoadSubCommand(
949e046f02SJonas Devlieghere       "generate",
959e046f02SJonas Devlieghere       CommandObjectSP(new CommandObjectReproducerGenerate(interpreter)));
9615eacd74SJonas Devlieghere   LoadSubCommand("status", CommandObjectSP(
9715eacd74SJonas Devlieghere                                new CommandObjectReproducerStatus(interpreter)));
989e046f02SJonas Devlieghere }
999e046f02SJonas Devlieghere 
1009e046f02SJonas Devlieghere CommandObjectReproducer::~CommandObjectReproducer() = default;
101